/***************************************************************************
**
**  This file is part of QGpGuiTools.
**
**  This library is free software; you can redistribute it and/or
**  modify it under the terms of the GNU Lesser General Public
**  License as published by the Free Software Foundation; either
**  version 2.1 of the License, or (at your option) any later version.
**
**  This file 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 Lesser General Public
**  License for more details.
**
**  You should have received a copy of the GNU Lesser General Public
**  License along with this library; if not, write to the Free Software
**  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
**
**  See http://www.geopsy.org for more information.
**
**  Created: 2004-04-28
**  Copyright: 2004-2019
**    Marc Wathelet
**    Marc Wathelet (ULg, Liège, Belgium)
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include "Settings.h"
#include "PrintDialogWrapper.h"
#include "Dialog.h"

#if(QT_VERSION > QT_VERSION_CHECK(5, 0, 0))
#include <QtPrintSupport>
#endif

namespace QGpGuiTools {

/*!
  Load the widget's rectangle from the registry
*/
void Settings::getRect(QWidget * w, QString name)
{
  TRACE;
  if(name.isEmpty()) {
    name=w->objectName();
  }
  ASSERT(!name.isEmpty());
  bool ok, allOk=true;
  QSettings& reg=CoreApplication::instance()->settings();
  reg.beginGroup("WidgetRect");
  reg.beginGroup(name);
  if(reg.contains("x")) {
    int x=reg.value("x", w->x()).toInt(&ok);
    if(!ok) allOk=false;
    int y=reg.value("y", w->y()).toInt(&ok);
    if(!ok) allOk=false;
    int width=reg.value("width", w->width()).toInt(&ok);
    if(!ok) allOk=false;
    int height=reg.value("height", w->height()).toInt(&ok);
    if(!ok) allOk=false;
    if(allOk) {
      QDesktopWidget * desktop=QApplication::desktop();
      QRect r;
      if(w->parentWidget()) {
        // On the screen of the parent widget, usually dialog boxes
        r=desktop->screenGeometry(w->parentWidget());
      } else {
        r=desktop->screenGeometry(w);
      }
      // QDesktopWidget::availableGeometry() does not work perfectly under Linux KDE Gentoo at least
      // prefer our old manual method.
#if defined(Q_OS_WIN)
      if(y<40) y=40;
      y-=20;
#endif
      if(x<r.left()) {
        x=r.left();
      } else if(x>r.right()-width) {
        if(width>r.width()) {
          width=r.right()-x;
        } else {
          x=r.right()-width;
        }
      }
      if(y<r.top()) {
        y=r.top();
      } else if(y>r.bottom()-height) {
        if(height>r.height()) {
          height=r.bottom()-y;
        } else {
          y=r.bottom()-height;
        }
      }

      w->move(x, y);
      if(width>0 && height>0) {
        w->resize(width, height);
      }
    }
  }
}

/*!
  Save the widget's rectangle in the registry if widget is visible

  Be careful not to use QDialog if you want to save rectangles to registry, but Dialog.
*/
void Settings::setRect(QWidget * w, QString name)
{
  TRACE;
  if(name.isEmpty()) {
    name=w->objectName();
  }
  ASSERT(!name.isEmpty());
  Dialog * d=qobject_cast<Dialog *>(w);
  if(d) {
    d->setRect(name);
  } else {
    QSettings& reg=CoreApplication::instance()->settings();
    reg.beginGroup("WidgetRect");
    reg.beginGroup(name);
    reg.setValue("x", w->x());
    reg.setValue("y", w->y());
    reg.setValue("width", w->width());
    reg.setValue("height", w->height());
  }
}

/*!
  Load the widget's size from the registry
*/
void Settings::getSize(QWidget * w, QString name)
{
  TRACE;
  if(name.isEmpty()) {
    name=w->objectName();
  }
  ASSERT(!name.isEmpty());
  QSettings& reg=CoreApplication::instance()->settings();
  bool ok, allOk=true;
  reg.beginGroup("WidgetRect");
  reg.beginGroup(name);
  int width=reg.value("width", w->width()).toInt(&ok);
  if(!ok) allOk=false;
  int height=reg.value("height", w->height()).toInt(&ok);
  if(!ok) allOk=false;
  if(allOk) {
    if(width<=0 || height<=0) {
      w->showMaximized();
    } else {
      w->resize(width, height);
    }
  }
}

/*!
  Save the widget's size in the registry (not the position)
*/
void Settings::setSize(QWidget * w, QString name)
{
  TRACE;
  if(name.isEmpty()) {
    name=w->objectName();
  }
  ASSERT(!name.isEmpty());
  QSettings& reg=CoreApplication::instance()->settings();
  reg.beginGroup("WidgetRect");
  reg.beginGroup(name);
  if(w->isMaximized()) {
    reg.setValue("width", -1);
    reg.setValue("height", -1);
  } else {
    reg.setValue("width", w->width());
    reg.setValue("height", w->height());
  }
}

/*!
  Load a path from the registry
*/
QString Settings::getPath(QString name)
{
  TRACE;
  QSettings& reg=CoreApplicationPrivate::instance()->globalSettings();
  reg.beginGroup("CurrentDirectories");
  if(reg.contains(name)) {
    QDir d(reg.value(name).toString());
    if(d.exists()) {
      return d.absolutePath();
    }
  }
  return QDir::currentPath ();
}

/*!
  Save a path in the registry
*/
void Settings::setPath(QString name, QDir dirPath)
{
  TRACE;
  QSettings& reg=CoreApplicationPrivate::instance()->globalSettings();
  reg.beginGroup("CurrentDirectories");
  QString p=dirPath.canonicalPath();
  reg.setValue(name, p);
  // Set current directory to dirPath, in case of uninitialized path
  // See getPath()
  QDir::setCurrent(p);
}

/*!
  Load current filter from the registry
*/
QString Settings::getFilter(QString name)
{
  TRACE;
  QSettings& reg=CoreApplicationPrivate::instance()->globalSettings();
  reg.beginGroup("CurrentFilters");
  QString f=reg.value(name).toString();
  return f;
}

/*!
  Save current filter in the registry
*/
void Settings::setFilter(QString name, QString filter)
{
  TRACE;
  QSettings& reg=CoreApplicationPrivate::instance()->globalSettings();
  reg.beginGroup("CurrentFilters");
  reg.setValue(name, filter);
}

/*!
  Save current tab index
*/
void Settings::setActiveTab(QTabWidget * w, QString name)
{
  TRACE;
  ASSERT(!w->objectName().isEmpty());
  QSettings& reg=CoreApplication::instance()->settings();
  reg.beginGroup("DialogOptions");
  reg.beginGroup(name);
  reg.setValue(w->objectName(), w->currentIndex());
}

/*!
  restore current tab index
*/
void Settings::activeTab(QTabWidget * w, QString name)
{
  TRACE;
  ASSERT(!w->objectName().isEmpty());
  QSettings& reg=CoreApplication::instance()->settings();
  reg.beginGroup("DialogOptions");
  reg.beginGroup(name);
  QVariant val=reg.value(w->objectName());
  if(!val.isValid()) return;
  w->setCurrentIndex(val.toInt());
}

/*!
  save splitter positions
*/
void Settings::setSplitter(QSplitter * w, QString name)
{
  TRACE;
  ASSERT(!w->objectName().isEmpty());
  QSettings& reg=CoreApplication::instance()->settings();
  reg.beginGroup("DialogOptions");
  reg.beginGroup(name);
  QStringList list;
  QList<int> intList=w->sizes();
  int val;
  foreach(val, intList) list << QString::number(val);
  reg.setValue(w->objectName(), list);
}

/*!
  restore splitter positions
*/
void Settings::splitter(QSplitter * w, QString name)
{
  TRACE;
  ASSERT(!w->objectName().isEmpty());
  QSettings& reg=CoreApplication::instance()->settings();
  reg.beginGroup("DialogOptions");
  reg.beginGroup(name);
  QVariant val=reg.value(w->objectName());
  if(!val.isValid()) return;
  QStringList list=val.toStringList();
  QList<int> intList;
  foreach(val, list) intList << val.toInt();
  w->setSizes(intList);
}

/*!
  save columms widths
*/
void Settings::setColumnWidth(QTableView * w, QString name)
{
  TRACE;
  ASSERT(!w->objectName().isEmpty());
  QSettings& reg=CoreApplication::instance()->settings();
  reg.beginGroup("DialogOptions");
  reg.beginGroup(name);
  QStringList colWidthList;
  int n=w->model()->columnCount();
  for(int i=0; i<n; i++) {
    colWidthList << QString::number(w->columnWidth(i));
  }
  reg.setValue(w->objectName(), colWidthList);
}

/*!
  restore columms widths
*/
void Settings::columnWidth(QTableView * w, QString name)
{
  TRACE;
  ASSERT(!w->objectName().isEmpty());
  QSettings& reg=CoreApplication::instance()->settings();
  reg.beginGroup("DialogOptions");
  reg.beginGroup(name);
  if(reg.contains(w->objectName())) {
    QStringList colWidthList=reg.value(w->objectName()).toStringList();
    int n=colWidthList.count();
    if(w->model()->columnCount()<n) n=w->model()->columnCount();
    for(int i=0; i<n; i++) {
      w->setColumnWidth(i, colWidthList.at(i).toInt());
    }
  }
}

/*!
  save columms widths
*/
void Settings::setColumnWidth(QTreeView * w, QString name)
{
  TRACE;
  ASSERT(!w->objectName().isEmpty());
  QSettings& reg=CoreApplication::instance()->settings();
  reg.beginGroup("DialogOptions");
  reg.beginGroup(name);
  QStringList colWidthList;
  int n=w->model()->columnCount();
  for(int i=0; i<n; i++) {
    colWidthList << QString::number(w->columnWidth(i));
  }
  reg.setValue(w->objectName(), colWidthList);
}

/*!
  restore columms widths
*/
void Settings::columnWidth(QTreeView * w, QString name)
{
  TRACE;
  ASSERT(!w->objectName().isEmpty());
  QSettings& reg=CoreApplication::instance()->settings();
  reg.beginGroup("DialogOptions");
  reg.beginGroup(name);
  if(reg.contains(w->objectName())) {
    QStringList colWidthList=reg.value(w->objectName()).toStringList();
    int n=colWidthList.count();
    if(w->model()->columnCount()<n) n=w->model()->columnCount();
    for(int i=0; i<n; i++) {
      w->setColumnWidth(i, colWidthList.at(i).toInt());
    }
  }
}

/*!
  Load the widget's settings from the registry.

  Only the Qt common widgets are loaded.
*/
void Settings::getWidget(QWidget * d, QString name, bool rect)
{
  TRACE;
  if(name.isEmpty()) {
    name=d->objectName();
  }
  ASSERT(!name.isEmpty());
  if(rect) getRect(d, name);
  QSettings& reg=CoreApplication::instance()->settings();
  reg.beginGroup("DialogOptions");
  reg.beginGroup(name);
  getWidget(reg, d->children());
}

void Settings::getWidget(QSettings& reg, const QObjectList & list)
{
  TRACE;
  for(QObjectList::const_iterator it=list.begin();it!=list.end();++it) {
    QWidget * child=qobject_cast<QWidget *>(*it);
    if(!child) continue;
    const QObjectList & childList=child->children();
    if(!childList.isEmpty()) {
      if(child->objectName().isEmpty()) {
        getWidget(reg, childList);
      } else {
        reg.beginGroup(child->objectName());
        getWidget(reg, childList);
        reg.endGroup();
      }
    }
    bool ok=true;
    const char * className=child->metaObject()->className();
    // Restore specific widget data
    if(child->objectName().isEmpty() || !reg.contains(child->objectName())) continue;
    QVariant val=reg.value(child->objectName());
    if(!val.isValid()) continue;
    child->blockSignals(true);
    switch (className[1]) {
    case 'C':
      if(strcmp(className, "QComboBox")==0) {
        QComboBox * w=static_cast<QComboBox *>(child);
        if(w->isEditable()) {
          w->setEditText(val.toString());
        } else {
          int index=w->findText(val.toString());
          if(index>-1) {
            w->setCurrentIndex(index);
          }
        }
      } else if(strcmp(className, "QCheckBox")==0) {
        static_cast<QCheckBox *>(child)->setChecked(val.toBool());
      }
      break;
    case 'D':
      if(strcmp(className, "QDoubleSpinBox")==0) {
        QDoubleSpinBox * sb=static_cast<QDoubleSpinBox*>(child);
        double spinVal=val.toDouble(&ok);
        if(ok) sb->setValue(spinVal);
      } else if(strcmp(className, "QDateEdit")==0 &&
                !child->parent()->inherits("QDateTimeEdit")) {
        QString str=val.toString();
        if(!str.isEmpty()) {
          QDate td;
          td.setDate(str.section("/", 2, 2).toInt(),
                     str.section("/", 1, 1).toInt(),
                     str.section("/", 0, 0).toInt());
          if(td.isValid()) static_cast<QDateEdit *>(child)->setDate(td);
        }
      } else if(strcmp(className, "QDateTimeEdit")==0) {
        QString str=val.toString();
        if(!str.isEmpty()) {
          QTime tt;
          QDate td;
          QString d=str.section(" ", 0, 0);
          td.setDate(d.section("/", 2, 2).toInt(),
                     d.section("/", 1, 1).toInt(),
                     d.section("/", 0, 0).toInt());
          QString t=str.section(" ", 1, 1);
          tt.setHMS(t.section(":", 0, 0).toInt(),
                    t.section(":", 1, 1).toInt(),
                    t.section(":", 2, 2).toInt());
          if(tt.isValid() && td.isValid()) static_cast<QDateTimeEdit *>(child)->setDateTime(QDateTime(td, tt));
        }
      }
      break;
    case 'G':
      if(strcmp(className, "QGpGuiTools::DoubleSpinBox")==0) {
        QStringList propList=val.toStringList();
        QDoubleSpinBox * sb=static_cast<QDoubleSpinBox*>(child);
        if(propList.count()==3) {
          sb->setDecimals(propList[0].toInt());
          sb->setSingleStep(propList[1].toDouble());
          sb->setValue(propList[2].toDouble());
        }
      } else if(strcmp(className, "QGroupBox")==0) {
        QGroupBox * w=static_cast<QGroupBox *>(child);
        if(w->isCheckable())
          w->setChecked(val.toBool());
      }
      break;
    case 'L':
      if(strcmp(className, "QLineEdit")==0) {
        if(child->objectName()!="qt_spinbox_lineedit")
          static_cast<QLineEdit*>(child)->setText(val.toString());
      } else if(strcmp(className, "QListWidget")==0 &&
                  child->objectName()!="in-combo") {
        QListWidget * list=static_cast<QListWidget *>(child);
        if(list->selectionMode()==QAbstractItemView::MultiSelection ||
           list->selectionMode()==QAbstractItemView::ExtendedSelection) {
          QStringList selList=val.toStringList();
          QString str;
          QListWidgetItem * item;
          foreach(str, selList) {
            item=list->item(str.toInt());
            if(item) {
              item->setSelected(true);
            }
          }
        } else {
          int index=val.toInt(&ok);
          if(ok) list->setCurrentRow(index);
        }
      }
      break;
    case 'P':
      if(strcmp(className, "QPlainTextEdit")==0) {
        static_cast<QPlainTextEdit* >(child)->setPlainText(val.toString());
      }
      break;
    case 'R':
      if(strcmp(className, "QRadioButton")==0) {
        static_cast<QCheckBox *>(child)->setChecked(val.toBool());
      }
      break;
    case 'S':
      if(strcmp(className, "QSpinBox")==0) {
        int spinVal=val.toInt(&ok);
        if(ok) {
          static_cast<QSpinBox *>(child)->setValue(spinVal);
        }
      } else if(strcmp(className, "QSplitter")==0) {
        QStringList sizesList=val.toStringList();
        QList<int> intSizesList;
        QString str;
        foreach(str, sizesList) {
          int s=str.toInt();
          if(s==0) s=100; // Forbid total disappearing of widgets
          intSizesList << s;
        }
        static_cast<QSplitter *>(child)->setSizes(intSizesList);
      }
      break;
    case 'T':
      if(strcmp(className, "QTabWidget")==0) {
        int index=val.toInt(&ok);
        if(ok && index<static_cast<QTabWidget *>(child)->count())
          static_cast<QTabWidget *>(child)->setCurrentIndex(index);
      } else if(strcmp(className, "QTextEdit")==0) {
        static_cast<QTextEdit *>(child)->setPlainText(val.toString());
      } else if(strcmp(className, "QTimeEdit")==0 &&
                !child->parent()->inherits("QDateTimeEdit")) {
        QString str=val.toString();
        if(!str.isEmpty()) {
          QTime tt;
          tt.setHMS(str.section(":", 0, 0).toInt(),
                    str.section(":", 1, 1).toInt(),
                    str.section(":", 2, 2).toInt());
          if(tt.isValid()) static_cast<QTimeEdit *>(child)->setTime(tt);
        }
      }
      break;
    default:
      break;
    }
    child->blockSignals(false);
  }
}

/*!
  Save widget's settings into the registry

  Be careful not to use QDialog if you want to save rectangles to registry, but Dialog.
*/
void Settings::setWidget(QWidget * d, QString name, bool rect)
{
  TRACE;
  if(name.isEmpty()) {
    name=d->objectName();
  }
  ASSERT(!name.isEmpty());
  if(rect) setRect(d, name);
  QSettings& reg=CoreApplication::instance()->settings();
  reg.beginGroup("DialogOptions");
  reg.beginGroup(name);
  setWidget(reg, d->children());
}

void Settings::setWidget(QSettings& reg, const QObjectList & list)
{
  TRACE;
  for(QObjectList::const_iterator it=list.begin();it!=list.end();++it) {
    QWidget * child=qobject_cast<QWidget *>(*it);
    if(!child) continue;
    const QObjectList & childList=child->children();
    if(!childList.isEmpty()) {
      if(child->objectName().isEmpty()) {
        setWidget(reg, childList);
      } else {
        reg.beginGroup(child->objectName());
        setWidget(reg, childList);
        reg.endGroup();
      }
    }
    if(child->objectName().isEmpty()) continue;
    const char * className=child->metaObject()->className();
    switch (className[ 1 ]) {
    case 'C':
      if(strcmp(className, "QComboBox")==0) {
        reg.setValue(child->objectName(), static_cast<QComboBox*>(child)->currentText());
      } else if(strcmp(className, "QCheckBox")==0) {
        reg.setValue(child->objectName(), static_cast<QCheckBox*>(child)->isChecked());
      }
      break;
    case 'D':
      if(strcmp(className, "QDoubleSpinBox")==0) {
        QDoubleSpinBox * sb=static_cast<QDoubleSpinBox*>(child);
        reg.setValue(child->objectName(), sb->value());
      } else if(strcmp(className, "QDateEdit")==0 &&
           !child->parent()->inherits("QDateTimeEdit")) {
        QDate d(static_cast<QDateEdit *>(child)->date());
        reg.setValue(child->objectName(), d.toString("dd/MM/yyyy"));
      } else if(strcmp(className, "QDateTimeEdit")==0) {
        QDateTime dt(static_cast<QDateTimeEdit *>(child)->dateTime());
        reg.setValue(child->objectName(), dt.toString("dd/MM/yyyy hh:mm:ss"));
      }
      break;
    case 'G':
      if(strcmp(className, "QGpGuiTools::DoubleSpinBox")==0) {
        QDoubleSpinBox * sb=static_cast<QDoubleSpinBox*>(child);
        QStringList propList;
        propList << QString::number(sb->decimals());
        propList << QString::number(sb->singleStep());
        propList << QString::number(sb->value());
        reg.setValue(child->objectName(), propList);
      } else if(strcmp(className, "QGroupBox")==0) {
        QGroupBox * w=static_cast<QGroupBox *>(child);
        if(w->isCheckable()) {
          reg.setValue(child->objectName(), w->isChecked());
        }
      }
      break;
    case 'L':
      if(strcmp(className, "QLineEdit")==0) {
        reg.setValue(child->objectName(), static_cast<QLineEdit *>(child)->text());
      } else if(strcmp(className, "QListWidget")==0 &&
                  child->objectName()!="in-combo") {
        QListWidget * list=static_cast<QListWidget *>(child);
        if(list->selectionMode()==QAbstractItemView::MultiSelection ||
             list->selectionMode()==QAbstractItemView::ExtendedSelection) {
          QStringList selList;
          for(int i=0; i<list->count();i++) {
            if(list->item(i)->isSelected()) {
              selList << QString::number(i);
            }
           }
          reg.setValue(child->objectName(), selList);
        } else reg.setValue(child->objectName(), list->currentRow());
      }
      break;
    case 'P':
      if(strcmp(className, "QPlainTextEdit")==0) {
        QPlainTextEdit * w=static_cast<QPlainTextEdit* >(child);
        if(!w->isReadOnly()) {
          reg.setValue(child->objectName(), w->toPlainText());
        } else {
          reg.remove(child->objectName()); // older releases may have dropped garbage there
        }
      }
      break;
    case 'R':
      if(strcmp(className, "QRadioButton")==0) {
        reg.setValue(child->objectName(), static_cast<QRadioButton *>(child)->isChecked());
      }
      break;
    case 'S':
      if(strcmp(className, "QSpinBox")==0) {
        reg.setValue(child->objectName(), static_cast<QSpinBox *>(child)->value());
      } else if(strcmp(className, "QSplitter")==0) {
        QStringList sizesList;
        QList<int> intSizeList=static_cast<QSplitter *>(child)->sizes();
        int val;
        foreach(val, intSizeList) {
          sizesList << QString::number(val);
        }
        reg.setValue(child->objectName(), sizesList);
      }
      break;
    case 'T':
      if(strcmp(className, "QTabWidget")==0) {
        reg.setValue(child->objectName(), static_cast<QTabWidget *>(child)->currentIndex());
      } else if(strcmp(className, "QTextEdit")==0) {
        reg.setValue(child->objectName(), static_cast<QTextEdit *>(child)->toPlainText());
      } else if(strcmp(className, "QTimeEdit")==0 &&
                  !child->parent()->inherits("QDateTimeEdit")) {
        QTime t(static_cast<QTimeEdit *>(child)->time());
        reg.setValue(child->objectName(), t.toString("hh:mm:ss"));
      }
      break;
    default:
      break;
    }
  }
}

/*!
  QInputDialog::getText with save-retore mechanism
*/
QString Settings::getText(QWidget * parent, const QString & caption,
                          const QString & label, QLineEdit::EchoMode mode,
                          const QString & text, bool * ok)
{
  TRACE;
  QSettings& reg=CoreApplication::instance()->settings();
  reg.beginGroup("DialogOptions");
  QString t=reg.value(caption).toString();
  if(!text.isEmpty()) t=text;
  QInputDialog * d=new QInputDialog(parent);
  d->setWindowTitle(caption);
  d->setLabelText(label);
  d->setInputMode(QInputDialog::TextInput);
  d->setTextEchoMode(mode);
  d->setTextValue(t);
  QString res;
  Settings::getRect(d, caption);
  if(d->exec()==QDialog::Accepted) {
    *ok=true;
    res=d->textValue();
    reg.setValue(caption, res);
    Settings::setRect(d, caption);
  }
  delete d;
  return res;
}

/*!
  Set printer information from settings and/or user dialog
*/
bool Settings::printSetup(QPrinter * p)
{
  TRACE;
  QSettings& reg=CoreApplication::instance()->settings();
  reg.beginGroup("PrintOptions");
  if(reg.contains("printerName")) {
    p->setPrinterName(reg.value("printerName").toString());
  }
  if(reg.contains("outputFileName")) {
    p->setOutputFileName(reg.value("outputFileName").toString());
  }
  if(reg.contains("orientation")) {
    p->setOrientation(static_cast<QPrinter::Orientation>(reg.value("orientation").toInt()));
  }
  if(reg.contains("pageSize")) {
    p->setPaperSize(static_cast<QPrinter::PaperSize>(reg.value("pageSize").toInt()));
  }
  if(reg.contains("pageOrder")) {
    p->setPageOrder(static_cast<QPrinter::PageOrder>(reg.value("pageOrder").toInt()));
  }
  if(reg.contains("paperSource")) {
    p->setPaperSource(static_cast<QPrinter::PaperSource>(reg.value("paperSource").toInt()));
  }
  if(reg.contains("numCopies")) {
    p->setNumCopies(reg.value("numCopies").toInt());
  }
  if(reg.contains("outputFormat")) {
    p->setOutputFormat(static_cast<QPrinter::OutputFormat>(reg.value("outputFormat").toInt()));
  }
  if(reg.contains("colorMode")) {
    p->setColorMode(static_cast<QPrinter::ColorMode>(reg.value("colorMode").toInt()));
  }
  if(reg.contains("printRange")) {
    p->setPrintRange(static_cast<QPrinter::PrintRange>(reg.value("printRange").toInt()));
  }
  if(reg.contains("toPage") && reg.contains("fromPage")) {
    p->setFromTo(reg.value("fromPage").toInt(), reg.value("toPage").toInt());
  }
  if(reg.contains("collateCopies")) {
    p->setCollateCopies(reg.value("collateCopies").toBool());
  }

  p->setCreator(QApplication::applicationName());
  QPrintDialog pd(p);
  PrintDialogWrapper pdWrap(&pd);

  if(pd.exec()==QDialog::Accepted) {
    reg.setValue("printerName", p->printerName());
    reg.setValue("outputFileName", p->outputFileName());
    reg.setValue("orientation", p->orientation());
    reg.setValue("pageSize", p->pageSize());
    reg.setValue("pageOrder", p->pageOrder());
    reg.setValue("paperSource", p->paperSource());
    reg.setValue("numCopies", p->numCopies());
    reg.setValue("outputFormat", p->outputFormat());
    reg.setValue("colorMode", p->colorMode());
    reg.setValue("printRange", p->printRange());
    reg.setValue("fromPage", p->fromPage());
    reg.setValue("toPage", p->toPage());
    reg.setValue("collateCopies", p->collateCopies());
    return true;
  } else {
    return false;
  }
}

/*!
  Restores history from registry
*/
QStringList Settings::getHistory(QSettings &reg, const QString &name)
{
  TRACE;
  // Some null strings were introduced by older release... filter them out here.
  QStringList list=reg.value(name).toStringList();
  int i;
  while((i=list.indexOf(QString()))>-1) {
    list.removeAt(i);
  }
  return list;
}

/*!
  Saves the directory history to registry
*/
void Settings::setHistory(QSettings &reg, const QString &name, const QString &newString, int maxCount)
{
  TRACE;
  if(!newString.isEmpty()) {
    QStringList list=reg.value(name).toStringList();
    int i=list.indexOf(newString);
    if(i>-1) {
      list.removeAt(i);
    }
    list.prepend(newString);
    while(list.count()>maxCount) list.removeLast();
    reg.setValue(name, list);
  }
}

void Settings::removeHistory(QSettings &reg, const QString &name, const QString &string)
{
  TRACE;
  QStringList list=reg.value(name).toStringList();
  int i=list.indexOf(string);
  if(i>-1) {
    list.removeAt(i);
    reg.setValue(name, list);
  }
}

/*!
  Restores the directory history from registry
*/
QStringList Settings::getDirHistory(const QString &caption)
{
  TRACE;
  QSettings& reg=CoreApplicationPrivate::instance()->globalSettings();
  reg.beginGroup("DirectoryHistories");
  QStringList l=getHistory(reg, "common");
  l+=getHistory(reg, caption);
  // Check that all items exit
  for(int i=l.count()-1; i>=0; i--) {
    const QString &path=l.at(i);
    QDir d(path);
    if(!d.exists()) {
      removeHistory(reg, "common", path);
      removeHistory(reg, caption, path);
      l.removeAt(i);
    }
  }
  // Add current directory
  QDir d;
  l.prepend(d.absolutePath());
  return l;
}

/*!
  Saves the directory history to registry
*/
void Settings::setDirHistory(const QString &caption, const QDir &newPath)
{
  TRACE;
  QSettings& reg=CoreApplicationPrivate::instance()->globalSettings();
  reg.beginGroup("DirectoryHistories");
  setHistory(reg, caption, newPath.canonicalPath(), 17);
  setHistory(reg, "common", newPath.canonicalPath(), 3);
}

/*!
  Restores history from registry
*/
QStringList Settings::getHistory(const QString &name)
{
  TRACE;
  QSettings& reg=CoreApplication::instance()->settings();
  return Settings::getHistory(reg, name);
}

/*!
  Saves the directory history to registry
*/
void Settings::setHistory(const QString &name, const QString &newString, int maxCount)
{
  TRACE;
  QSettings& reg=CoreApplication::instance()->settings();
  Settings::setHistory(reg, name, newString, maxCount);
}

void Settings::removeHistory(const QString &name, const QString &string)
{
  TRACE;
  QSettings& reg=CoreApplication::instance()->settings();
  Settings::removeHistory(reg, name, string);
}

} // namespace QGpGuiTools
