Logo Search packages:      
Sourcecode: qbrew version File versions

qbrew.cpp

/***************************************************************************
  qbrew.cpp
  -------------------
  Control class for QBrew
  -------------------
  Copyright (c) 2006-2007 David Johnson
  Please see the header file for copyright and license information.
***************************************************************************/

#include <QtGui>

#include "alcoholtool.h"
#include "configure.h"
#include "data.h"
#include "databasetool.h"
#include "recipe.h"
#include "helpviewer.h"
#include "hydrometertool.h"
#include "resource.h"
#include "view.h"

#include "qbrew.h"

using namespace Resource;

QBrew *QBrew::instance_ = 0;
static QMutex instancelock;

//////////////////////////////////////////////////////////////////////////////
// Construction, Destruction, Initialization                                //
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
// QBrew()
// ------------
// Private constructor

QBrew::QBrew()
    : data_(0), recipe_(0), view_(0), alcoholtool_(0), databasetool_(0),
      hydrometertool_(0), configure_(0), handbook_(0), primer_(0), state_(),
      filename_(), newflag_(false), backed_(false), autosave_(0),
      autosavename_(), printer_(0)
{ ; }

//////////////////////////////////////////////////////////////////////////////
// initialize()
// ------------
// Initialize mainwindow

void QBrew::initialize(const QString &filename)
{
    setAttribute(Qt::WA_DeleteOnClose);
    readConfig();

    // show splashscreen
    if (state_.general.showsplash
        && QFile::exists(dataBase() + "splash.png")) {
      QSplashScreen *splash  = new QSplashScreen(dataBase() + "splash.png",
                                     Qt::WindowStaysOnTopHint);
        splash->show();
        QApplication::flush();
        QTimer::singleShot(3000, splash, SLOT(close()));
    }

    // setup look and feel
    setWindowIcon(QIcon(":/pics/qbrew.png"));
    if ((state_.general.lookfeel != QApplication::style()->objectName()) &&
        (QStyleFactory::keys().contains(state_.general.lookfeel))) {
        QApplication::setStyle(state_.general.lookfeel);
    }

    // setup UI
    ui.setupUi(this);
    initActions();

    // restore window state
    restoreState();

    // initialize data
    data_ = Data::instance();
    data_->initialize(state_);

    // initialize calculations
    data_->setEfficiency(state_.calc.efficiency);
    data_->setTinseth(state_.calc.tinseth);
    data_->setMorey(state_.calc.morey);

    // create recipe
    recipe_ = new Recipe(this);
    connect(recipe_, SIGNAL(recipeModified()), this, SLOT(recipeModified()));

    // create view
    view_ = new View(this, recipe_);

    // load or create a recipe
    bool emptyfilename = (filename.isEmpty() || (filename == DEFAULT_FILE));
    if (emptyfilename &&
        (state_.general.loadlast && !state_.general.recentfiles.isEmpty())) {
        if (QFile::exists(state_.general.recentfiles.first())) {
            filename_ = state_.general.recentfiles.first();
        }
    } else {
        filename_ = filename;
    }
    emptyfilename = (filename_.isEmpty() || (filename_ == DEFAULT_FILE));
    if (!emptyfilename) {
        openFile(filename_);
    } else {
        recipe_->newRecipe();
        newflag_ = true;
        backed_ = false;
        filename_ = DEFAULT_FILE + "." + FILE_EXT;
        setWindowTitle(TITLE + " " + VERSION + " [*]");
    }

    // connections
    connect(ui.menuopenrecent, SIGNAL(aboutToShow()),
            this, SLOT(recentMenuShow()));

    // other initialization
    initAutoSave();
    setCentralWidget(view_);
    view_->refresh();
}

//////////////////////////////////////////////////////////////////////////////
// ~QBrew()
// -------------
// Private destructor

QBrew::~QBrew()
{
    saveState();

    // make sure any open windows are closed
    if (alcoholtool_) alcoholtool_->close();
    if (hydrometertool_) hydrometertool_->close();
    if (databasetool_) databasetool_->close();
    if (configure_) configure_->close();
    if (handbook_) handbook_->close();
    if (primer_) primer_->close();
}

//////////////////////////////////////////////////////////////////////////////
// instance()
// ----------
// Return pointer to the instance

QBrew *QBrew::instance()
{
    if (!instance_) {
        QMutexLocker lock(&instancelock);
        if (!instance_) instance_ = new QBrew();
    }
    return instance_;
}

//////////////////////////////////////////////////////////////////////////////
// initActions()
// -------------
// Initialize the actions

void QBrew::initActions()
{
    connect(ui.actionfilenew, SIGNAL(triggered()), this, SLOT(fileNew()));
    connect(ui.actionfileopen, SIGNAL(triggered()), this,  SLOT(fileOpen()));
    connect(ui.actionfilesave, SIGNAL(triggered()), this, SLOT(fileSave()));
    connect(ui.actionfilesaveas, SIGNAL(triggered()), this, SLOT(fileSaveAs()));
    connect(ui.actionfileprint, SIGNAL(triggered()), this, SLOT(filePrint()));
    connect(ui.actionfileexport, SIGNAL(triggered()), this, SLOT(fileExport()));
    connect(ui.actionexit, SIGNAL(triggered()), qApp, SLOT(closeAllWindows()));

    connect(ui.actionalcoholtool, SIGNAL(triggered()), this, SLOT(toolsAlcohol()));
    connect(ui.actionhydrometertool, SIGNAL(triggered()), this, SLOT(toolsHydrometer()));
    connect(ui.actiondatabasetool, SIGNAL(triggered()), this, SLOT(toolsDatabase()));

    connect(ui.actiontogglestatusbar, SIGNAL(toggled(bool)), this, SLOT(optionsStatusbar(bool)));
    connect(ui.actionconfigure, SIGNAL(triggered()), this, SLOT(optionsConfigure()));

    connect(ui.actionhelpcontents, SIGNAL(triggered()), this, SLOT(helpContents()));
    connect(ui.actionprimer, SIGNAL(triggered()), this, SLOT(helpPrimer()));
    connect(ui.actioncontexthelp, SIGNAL(triggered()), this, SLOT(helpContext()));
    connect(ui.actionabout, SIGNAL(triggered()), this, SLOT(helpAbout()));

    // insert toolbar toggle action
    ui.menuoptions->insertAction(ui.actiontogglestatusbar,
                                 ui.maintoolbar->toggleViewAction());
}

//////////////////////////////////////////////////////////////////////////////
// initAutoSave()
// ---------------
// Initialize the autosave timer

void QBrew::initAutoSave()
{
    // destroy existing timer, if any
    if (autosave_) {
        autosave_->stop();
        disconnect(autosave_, SIGNAL(timeout()), this, SLOT(autoSave()));
        delete autosave_; autosave_ = 0;
    }

    autosavename_ = QDir::currentPath()
        + QString("/autosave.%1").arg(FILE_EXT);

    if (state_.general.autosave) {
        autosave_ = new QTimer(this);
        connect(autosave_, SIGNAL(timeout()), this, SLOT(autoSave()));
        autosave_->start(state_.general.saveinterval * 60000);
    }
}

//////////////////////////////////////////////////////////////////////////////
// File Menu Implementation                                                 //
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
// fileNew()
// ---------
// Create a new recipe

void QBrew::fileNew()
{
    if (recipe_->modified()) {
        // query user to save file
        switch (querySave()) {
          case QMessageBox::Yes:
              fileSave();
              break;
          case QMessageBox::No:
              break;
          case QMessageBox::Cancel:
              statusBar()->showMessage("Canceled...", 2000);
              // exit function
              return;
        }
    }

    // create a new file
    recipe_->newRecipe();
    newflag_ = true;
    backed_ = false;

    ui.actionfilesave->setEnabled(true);

    filename_ = DEFAULT_FILE;
    setFileCaption(filename_);
    statusBar()->showMessage("Created new recipe", 2000);
}

//////////////////////////////////////////////////////////////////////////////
// fileOpen()
// ----------
// Open a recipe

void QBrew::fileOpen(const QString &filename)
{
    if (recipe_->modified()) {
        // query user to save file
        switch (querySave()) {
          case QMessageBox::Yes:
              fileSave();
              break;
          case QMessageBox::No:
              break;
          case QMessageBox::Cancel:
              statusBar()->showMessage("Canceled...", 2000);
              return;
        }
    }

    // open the file
    statusBar()->showMessage("Opening recipe...");
    QString fname;
    if (filename.isEmpty()) {
        fname = QFileDialog::getOpenFileName(this,
                                             "Open...",
                                             QString(),
                                             OPEN_FILTER);
    } else {
        fname = filename;
    }
    if (openFile(fname)) {
        statusBar()->showMessage("Loaded recipe", 2000);
    } else {
        statusBar()->showMessage("Load failed", 2000);
    }
}

//////////////////////////////////////////////////////////////////////////////
// fileRecent()
// -----------
// Selection has been made from recent file menu

void QBrew::fileRecent()
{
    QAction *action = qobject_cast<QAction *>(sender());
    if (!action) return;

    if (recipe_->modified()) {
        // file needs to be saved, what do we do
        switch (querySave()) {
          case QMessageBox::Yes:
              fileSave();
              break;
          case QMessageBox::No:
              break;
          case QMessageBox::Cancel:
              statusBar()->showMessage("Canceled...", 2000);
              return;
        }
    }

    // open the file
    QString fname = action->text();
    if (openFile(fname)) {
        statusBar()->showMessage("Loaded recipe", 2000);
        addRecent(fname);
    }
}

//////////////////////////////////////////////////////////////////////////////
// fileSave()
// ----------
// Save a recipe

void QBrew::fileSave()
{
    if (newflag_) {
        fileSaveAs();
    } else {
        if (state_.general.autobackup) {
            if (!backupFile())
                QMessageBox::warning(this, TITLE,
                    QString("%1 was unable to make a backup of %2")
                                     .arg(PACKAGE).arg(filename_));
        }
        if (saveFile(filename_)) {
            // successful in saving file
            newflag_ = false;
            ui.actionfilesave->setEnabled(false);
            setFileCaption(filename_);
            statusBar()->showMessage("Saved recipe", 2000);
        } else {
            // error in saving file
            QMessageBox::warning(this, TITLE,
                                 QString("%1 was unable to save %2")
                                 .arg(PACKAGE).arg(filename_));
            statusBar()->showMessage("Error in saving recipe", 2000);
        }
    }
}

//////////////////////////////////////////////////////////////////////////////
// fileSaveAs()
// ------------
// Save a recipe under a new name

void QBrew::fileSaveAs()
{
    statusBar()->showMessage("Saving recipe under new filename...");
    QString fname = QFileDialog::getSaveFileName(this,
                                                 "Save As...",
                                                 QString(),
                                                 SAVE_FILTER);
    if (!fname.isEmpty()) { // we got a filename
        // add suffix if there is none
        if (!QFile::exists(fname)) {
            if (fname.indexOf('.') == -1) fname += '.' + FILE_EXT;
        }

        if (state_.general.autobackup) backupFile();
        if (QFile::exists(fname)) {
            // overwrite?
            switch (queryOverwrite(fname)) {
              case QMessageBox::Yes:
                  break;
              case QMessageBox::Cancel:
                  statusBar()->showMessage("Canceled...", 2000);
                  return;
            }
        }

        if (saveFile(fname)) {
            // successfully saved
            newflag_ = false;
            addRecent(fname);
            ui.actionfilesave->setEnabled(false);
            setFileCaption(fname);
            statusBar()->showMessage("Saved recipe", 2000);
            // save name of file
            filename_ = fname;
        } else {
            // error in saving
            QMessageBox::warning(this, TITLE,
                                 QString("Unable to save to %1")
                                 .arg(QFileInfo(filename_).fileName()));
            statusBar()->showMessage("Error in saving recipe", 2000);
        }
    } else {
        // no file chosen
        statusBar()->showMessage("Saving aborted", 2000);
    }
}

//////////////////////////////////////////////////////////////////////////////
// fileExport()
// ------------
// Export recipe to non-native format

void QBrew::fileExport()
{
    bool status = false;
    QString selected;

    // file dialog will swap extensions as necessary
    QString dirfile = filename_.left(filename_.lastIndexOf('.'))
        + '.' + EXPORT_EXT;
    QString fname  = QFileDialog::getSaveFileName(this,
                                                  "Export...",
                                                  dirfile,
                                                  EXPORT_FILTER,
                                                  &selected);


    if (!fname.isEmpty()) { // we got a filename
        // add suffix if there is none
        if (!QFile::exists(fname)) {
            if (fname.indexOf('.') == -1) {
               if (selected == HTML_FILTER) fname += ".html";
               else if (selected == PDF_FILTER) fname += ".pdf";
               else if (selected == TEXT_FILTER) fname += ".txt";
            }
        }

        if (QFile::exists(fname)) {
            // overwrite?
            switch (queryOverwrite(fname)) {
              case QMessageBox::Yes:
                  break;
              case QMessageBox::Cancel:
                  statusBar()->showMessage("Canceled...", 2000);
                  return;
            }
        }

        // export character
        if (selected == HTML_FILTER) {
            status = recipe_->exportHtml(fname);
        } else if (selected == BEERXML_FILTER) {
            status = recipe_->exportBeerXML(fname);
        } else if (selected == PDF_FILTER) {
            status = recipe_->exportPdf(fname);
        } else if (selected == TEXT_FILTER) {
            status = recipe_->exportText(fname);
        }
        if (status) {
            // successfully exported
            statusBar()->showMessage("Exported recipe", 2000);
        } else {
            // error in exporting
            QMessageBox::warning(this, TITLE,
                                 QString("Unable to export to %1")
                                 .arg(QFileInfo(filename_).fileName()));
            statusBar()->showMessage("Error exporting recipe", 2000);
        }
    } else {
        // no file chosen
        statusBar()->showMessage("Export aborted", 2000 );
    }
}

//////////////////////////////////////////////////////////////////////////////
// filePrint()
// ------------
// Print the recipe

void QBrew::filePrint()
{
    statusBar()->showMessage("Printing...");

    if (!printer_) {
        printer_ = new QPrinter(QPrinter::HighResolution);
        printer_->setFullPage(true);
        printer_->setColorMode(QPrinter::GrayScale);

        // for convenience, default to US_Letter for C/US/Canada
        switch (QLocale::system().country()) {
          case QLocale::AnyCountry:
          case QLocale::Canada:
          case QLocale::UnitedStates:
          case QLocale::UnitedStatesMinorOutlyingIslands:
              printer_->setPageSize(QPrinter::Letter); break;
          default:
              printer_->setPageSize(QPrinter::A4); break;
        }
    }

    QPrintDialog pdialog(printer_, this);
    if (pdialog.exec() == QDialog::Accepted) {
        recipe_->printRecipe(printer_);
        statusBar()->showMessage(READY, 2000);
    } else {
        // cancelled
        statusBar()->showMessage("Printing cancelled", 2000);
    }
}

//////////////////////////////////////////////////////////////////////////////
// Tools Menu Implementation                                                //
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
// toolsAlcohol()
// --------------
// A utility dialog for hydrometer correction

void QBrew::toolsAlcohol()
{
    if (!alcoholtool_) alcoholtool_  = new AlcoholTool(this);
    alcoholtool_->show();
    alcoholtool_->raise();
    if (alcoholtool_->isMinimized()) alcoholtool_->showNormal();

    statusBar()->showMessage(READY, 2000);
}

//////////////////////////////////////////////////////////////////////////////
// toolsHydrometer()
// -----------------
// A utility dialog for hydrometer correction

void QBrew::toolsHydrometer()
{
    if (!hydrometertool_) hydrometertool_ = new HydrometerTool(this);
    hydrometertool_->show();
    hydrometertool_->raise();
    if (hydrometertool_->isMinimized()) hydrometertool_->showNormal();

    statusBar()->showMessage(READY, 2000);
}

//////////////////////////////////////////////////////////////////////////////
// toolsDatabase()
// ---------------
// A database editor for ingredients

void QBrew::toolsDatabase()
{
    if (!databasetool_)
        databasetool_ = new DatabaseTool(this);
    databasetool_->show();
    databasetool_->raise();
    if (databasetool_->isMinimized()) databasetool_->showNormal();

    statusBar()->showMessage(READY, 2000);
}

//////////////////////////////////////////////////////////////////////////////
// Options Menu Implementation                                              //
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
// optionsSatusbar()
// -----------------
// Toggle statusbar status

void QBrew::optionsStatusbar(bool on)
{
    statusBar()->setVisible(on);
    state_.window.statusbar = on;
    statusBar()->showMessage(READY, 2000);
}

//////////////////////////////////////////////////////////////////////////////
// optionsConfigure()
// ------------
// Display the configuration dialog

void QBrew::optionsConfigure()
{
    statusBar()->showMessage(QString("Configuring %1 ...").arg(PACKAGE), 2000);

    if (!configure_) {
        configure_ = new Configure(this);

        connect(configure_, SIGNAL(generalApply(const GenConfigState&)),
                this, SLOT(applyGeneralState(const GenConfigState&)));
        connect(configure_, SIGNAL(recipeApply(const RecipeConfigState&)),
                this, SLOT(applyRecipeState(const RecipeConfigState&)));
        connect(configure_, SIGNAL(calcApply(const CalcConfigState&)),
                this, SLOT(applyCalcState(const CalcConfigState&)));
        connect(configure_, SIGNAL(configureAccept()),
                this, SLOT(saveConfig()));
    }

    if (!configure_->isVisible()) {
        configure_->setState(state_);
    }
    configure_->show(); // non-modal
    configure_->raise();
    if (configure_->isMinimized()) configure_->showNormal();

    statusBar()->showMessage(READY, 2000);
}

//////////////////////////////////////////////////////////////////////////////
// Help Menu Implementation                                                 //
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
// helpContents()
// --------------
// Display the application manual

void QBrew::helpContents()
{
    QString home = docBase() + HELP_FILE;

    if (!handbook_) handbook_ = new HelpViewer(home, 0);
    handbook_->show();
    handbook_->raise();
    if (handbook_->isMinimized()) handbook_->showNormal();

    statusBar()->showMessage(READY, 2000);
}

//////////////////////////////////////////////////////////////////////////////
// helpPrimer()
// --------------
// Display the brewing primer

void QBrew::helpPrimer()
{
    QString home = docBase() + PRIMER_FILE;

    if (!primer_) primer_ = new HelpViewer(home, 0);
    primer_->show();
    primer_->raise();
    if (primer_->isMinimized()) primer_->showNormal();

    statusBar()->showMessage(READY, 2000);
}

//////////////////////////////////////////////////////////////////////////////
// helpContext()
// -------------
// Display context help cursor

void QBrew::helpContext()
{
    QWhatsThis::enterWhatsThisMode();
}

//////////////////////////////////////////////////////////////////////////////
// helpAbout()
// -----------
// Display the About dialog

void QBrew::helpAbout()
{
    QString message;

    message = "<center><nobr><big><strong>" + TITLE + " Version "
        + VERSION + "</strong></big></nobr></center>";
    message += "<p align=center><strong>" + DESCRIPTION + "</strong></p>";
    message += "<p align=center>" + COPYRIGHT + ' ' + AUTHOR + "</p>";
    message += "<p align=center><small>Contributions by "
        + CONTRIBUTORS + "</small></p>";

    QMessageBox::about(this, "About " + TITLE, message);
}

//////////////////////////////////////////////////////////////////////////////
// Settings                                                                 //
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
// applyGeneralState()
// -------------------
// Set the general configuration state

void QBrew::applyGeneralState(const GenConfigState &state)
{
    GenConfigState oldstate = state_.general;
    state_.general = state;

    // apply immediate state changes
    if (state.lookfeel != oldstate.lookfeel) {
        QApplication::setStyle(state.lookfeel);
    }
    if ((state.autosave != oldstate.autosave) ||
        (state.saveinterval != oldstate.saveinterval)) {
        initAutoSave();
    }
    if (state.recentnum < oldstate.recentnum) {
        while (state_.general.recentfiles.count() > state_.general.recentnum) {
            state_.general.recentfiles.pop_back();
        }
    }
    statusBar()->showMessage(READY, 2000);
}

//////////////////////////////////////////////////////////////////////////////
// applyRecipeState()
// ------------------
// Set the recipe configuration state

void QBrew::applyRecipeState(const RecipeConfigState &state)
{
    RecipeConfigState oldstate = state_.recipe;
    state_.recipe = state;

    // apply state changes
    if (state.batch != oldstate.batch) {
        if (state_.calc.units == UNIT_METRIC) {
            data_->setDefaultSize(Volume(state.batch, Volume::liter));
        } else if (state_.calc.units == UNIT_US) {
            data_->setDefaultSize(Volume(state.batch, Volume::gallon));
        }
    }
    if (state.style != oldstate.style) {
        data_->setDefaultStyle(state.style);
    }
    if (state.hopform != oldstate.hopform) {
        data_->setDefaultHopForm(state.hopform);
    }
    if (state.mash != oldstate.mash) {
        data_->setDefaultMash(state.mash);
    }

    statusBar()->showMessage(READY, 2000);
}

//////////////////////////////////////////////////////////////////////////////
// applyCalcState()
// ----------------
// Set the calc configuration state

void QBrew::applyCalcState(const CalcConfigState &state)
{
    CalcConfigState oldstate = state_.calc;
    state_.calc = state;

    // apply state changes
    if (state.efficiency != oldstate.efficiency) {
        data_->setEfficiency(state.efficiency);
    }
    if (state.morey != oldstate.morey) {
        data_->setMorey(state.morey);
    }
    if (state.tinseth != oldstate.tinseth) {
        data_->setTinseth(state.tinseth);
    }
    if (state.units != oldstate.units) {
        if (state.units == UNIT_METRIC) {
            data_->setDefaultSize(Volume(state_.recipe.batch,
                                          Volume::liter));
            data_->setDefaultGrainUnit(Weight::kilogram);
            data_->setDefaultHopUnit(Weight::gram);
        } else if (state.units == UNIT_US) {
            data_->setDefaultSize(Volume(state_.recipe.batch,
                                          Volume::gallon));
            data_->setDefaultGrainUnit(Weight::pound);
            data_->setDefaultHopUnit(Weight::ounce);
        }
    }

    // recalculate
    recipe_->recalc();
    view_->flush();

    statusBar()->showMessage(READY, 2000);
}

//////////////////////////////////////////////////////////////////////////////
// saveConfig()
// -----------
// Save the configuration (when OK pressed in dialog)

void QBrew::saveConfig()
{
    writeConfig();
    statusBar()->showMessage("Saved configuration", 2000);
}

//////////////////////////////////////////////////////////////////////////////
// readConfig()
// ------------
// Read configuration from settings file

void QBrew::readConfig()
{
    QSettings config("usermode.org", "QBrew");
    config.beginGroup(QString("/") + PACKAGE);

    // read general config
    config.beginGroup(CONFGROUP_GENERAL);
    state_.general.lookfeel =
        config.value(CONF_GEN_LOOK_FEEL, state_.general.lookfeel).toString();
    state_.general.showsplash =
        config.value(CONF_GEN_SHOW_SPLASH, state_.general.showsplash).toBool();
    state_.general.autosave =
        config.value(CONF_GEN_AUTOSAVE, state_.general.autosave).toBool();
    state_.general.saveinterval =
        config.value(CONF_GEN_SAVEINTERVAL, state_.general.saveinterval).toUInt();
    state_.general.autobackup =
        config.value(CONF_GEN_AUTOBACKUP, state_.general.autobackup).toBool();
    state_.general.loadlast =
        config.value(CONF_GEN_LOADLAST, state_.general.autobackup).toBool();
    state_.general.recentnum =
        config.value(CONF_GEN_RECENTNUM, state_.general.recentnum).toUInt();
    config.endGroup();

    // read recipe config
    config.beginGroup(CONFGROUP_RECIPE);
    state_.recipe.batch =
        config.value(CONF_RECIPE_BATCH, state_.recipe.batch).toDouble();
    state_.recipe.style =
        config.value(CONF_RECIPE_STYLE, state_.recipe.style).toString();
    state_.recipe.hopform =
        config.value(CONF_RECIPE_HOPFORM, state_.recipe.hopform).toString();
    state_.recipe.mash =
        config.value(CONF_RECIPE_MASH, state_.recipe.mash).toBool();
    config.endGroup();

    // read calc config
    config.beginGroup(CONFGROUP_CALC);
    state_.calc.efficiency =
        config.value(CONF_CALC_EFFICIENCY, state_.calc.efficiency).toDouble();
    state_.calc.morey =
        config.value(CONF_CALC_MOREY, state_.calc.morey).toBool();
    state_.calc.tinseth =
        config.value(CONF_CALC_TINSETH, state_.calc.tinseth).toBool();
    state_.calc.units =
        config.value(CONF_CALC_UNITS, state_.calc.units).toString();
    config.endGroup();

    config.endGroup();
}

//////////////////////////////////////////////////////////////////////////////
// writeConfig()
// -------------
// Write configuration to settings file

void QBrew::writeConfig()
{
    QSettings config("usermode.org", "QBrew");
    config.beginGroup(QString("/") + PACKAGE);

    // write general config
    config.beginGroup(CONFGROUP_GENERAL);
    config.setValue(CONF_GEN_LOOK_FEEL, state_.general.lookfeel);
    config.setValue(CONF_GEN_SHOW_SPLASH, state_.general.showsplash);
    config.setValue(CONF_GEN_AUTOSAVE, state_.general.autosave);
    config.setValue(CONF_GEN_SAVEINTERVAL, (int)state_.general.saveinterval);
    config.setValue(CONF_GEN_AUTOBACKUP, state_.general.autobackup);
    config.setValue(CONF_GEN_LOADLAST, state_.general.loadlast);
    config.setValue(CONF_GEN_RECENTNUM, (int)state_.general.recentnum);
    config.endGroup();

    // write recipe config
    config.beginGroup(CONFGROUP_RECIPE);
    config.setValue(CONF_RECIPE_BATCH, (double)state_.recipe.batch);
    config.setValue(CONF_RECIPE_STYLE, state_.recipe.style);
    config.setValue(CONF_RECIPE_HOPFORM, state_.recipe.hopform);
    config.setValue(CONF_RECIPE_MASH, state_.recipe.mash);
    config.endGroup();

    // write calc config
    config.beginGroup(CONFGROUP_CALC);
    config.setValue(CONF_CALC_EFFICIENCY, (double)state_.calc.efficiency);
    config.setValue(CONF_CALC_MOREY, state_.calc.morey);
    config.setValue(CONF_CALC_TINSETH, state_.calc.tinseth);
    config.setValue(CONF_CALC_UNITS, state_.calc.units);
    config.endGroup();

    config.endGroup();
}

//////////////////////////////////////////////////////////////////////////////
// restoreState()
// ------------
// Restore application state

void QBrew::restoreState()
{
    QSettings config("usermode.org", "QBrew");
    config.beginGroup(QString("/") + PACKAGE);

    // read window state
    config.beginGroup(CONFGROUP_WINDOW);
    state_.window.statusbar = config.value(CONF_WIN_STATUSBAR,
                                           state_.window.statusbar).toBool();

    QByteArray mainwindow = config.value(CONF_WIN_MAINWINDOW).toByteArray();
    QMainWindow::restoreState(mainwindow);
    resize(config.value(CONF_WIN_SIZE, QSize(600, 400)).toSize());
    config.endGroup();

    // read general state
    config.beginGroup(CONFGROUP_GENERAL);
    state_.general.recentfiles = config.value(CONF_GEN_RECENTFILES).toStringList();
    config.endGroup();

    config.endGroup();

    // show or hide statusbar depending on initial setting
    statusBar()->setVisible(state_.window.statusbar);
    ui.actiontogglestatusbar->setChecked(state_.window.statusbar);
}

//////////////////////////////////////////////////////////////////////////////
// saveSate()
// ----------
// Save application state

void QBrew::saveState()
{
    // load config from settings
    QSettings config("usermode.org", "QBrew");
    config.beginGroup(QString("/") + PACKAGE);

    // write window state
    config.beginGroup(CONFGROUP_WINDOW);
    config.setValue(CONF_WIN_MAINWINDOW, QMainWindow::saveState());
    config.setValue(CONF_WIN_SIZE, size());
    config.setValue(CONF_WIN_STATUSBAR, state_.window.statusbar);

    config.endGroup();

    // write general state
    config.beginGroup(CONFGROUP_GENERAL);
    config.setValue(CONF_GEN_RECENTFILES, state_.general.recentfiles);
    config.endGroup();

    config.endGroup();
}

//////////////////////////////////////////////////////////////////////////////
// Miscellaneous                                                            //
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
// openFile()
// ----------
// Open the named file

bool QBrew::openFile(const QString &filename)
{

    if (!filename.isEmpty()) {
        if (recipe_->nativeFormat(filename)) {
            if (recipe_->loadRecipe(filename)) {
                filename_ = filename;
                setFileCaption(filename_);
            } else {
                // load was unsuccessful
                QMessageBox::warning(this, TITLE,
                                     QString("Unable to load the recipe ")
                                     .arg(QFileInfo(filename_).fileName()));
                return false;
            }
        } else {
            // attempt to import file
            if (recipe_->importRecipe(filename)) {
                // set filename to the default (forces a saveas)
                filename_ = DEFAULT_FILE;
                setFileCaption(filename_);
            } else {
                // import was unsuccessful
                QMessageBox::warning(this, TITLE,
                                     QString("Unable to import the file %1")
                                     .arg(QFileInfo(filename).fileName()));
                return false;
            }
        }

        newflag_ = false;
        backed_ = false;
        addRecent(filename_);
        ui.actionfilesave->setEnabled(false);

        return true;
    }
    // empty filename
    return false;
}

//////////////////////////////////////////////////////////////////////////////
// saveFile()
// ----------
// Save a file

bool QBrew::saveFile(const QString &filename)
{
    bool status = true;

    if (!filename.isEmpty()) {
        status = recipe_->saveRecipe(filename);

        if (status) {
            // remove old autosave file if present
            if (QFile::exists(autosavename_)) {
                QFile::remove(autosavename_);
                initAutoSave();
            }
        }
    }

    return status;
}

//////////////////////////////////////////////////////////////////////////////
// backupFile()
// ------------
// Backup the current file

bool QBrew::backupFile()
{
    if (backed_) return true;

    bool status = false;
    if ((!filename_.isEmpty()) && (filename_ != DEFAULT_FILE)) {
        if (QFile::exists(filename_ + '~'))
            QFile::remove(filename_ + '~');
        status = QFile::copy(filename_, filename_ + '~');
        if (status) backed_ = true;
    }
    return status;
}

//////////////////////////////////////////////////////////////////////////////
// recentMenuShow()
// ----------------
// about to show recent file menu

void QBrew::recentMenuShow()
{
    ui.menuopenrecent->clear();

    QAction *action;
    foreach(QString recentfile, state_.general.recentfiles) {
        action = new QAction(recentfile, ui.menuopenrecent);
        connect(action, SIGNAL(triggered()),
                this, SLOT(fileRecent()));
      ui.menuopenrecent->addAction(action);
    }
}

//////////////////////////////////////////////////////////////////////////////
// addRecent()
// -----------
// Add a file to the recent files list

void QBrew::addRecent(const QString &filename)
{
    if (state_.general.recentnum == 0) return;

    QFileInfo finfo(filename);
    QString filepath = finfo.absoluteFilePath();

    if (state_.general.recentfiles.contains(filepath))
      state_.general.recentfiles.removeAll(filepath);
    if (state_.general.recentfiles.count() >= state_.general.recentnum)
      state_.general.recentfiles.removeLast();
    state_.general.recentfiles.prepend(filepath);
}

//////////////////////////////////////////////////////////////////////////////
// autoSave()
// ----------
// Time to autosave

void QBrew::autoSave()
{
    if (!recipe_->modified()) return;
    statusBar()->showMessage("Autosaving recipe...", 2000);
    if ((filename_.isEmpty()) || (filename_ == DEFAULT_FILE)) {
        recipe_->saveRecipe(autosavename_);
    } else {
        recipe_->saveRecipe(filename_);
    }
    // remove "modified" from caption
    setFileCaption(filename_);
}

//////////////////////////////////////////////////////////////////////////////
// setFileCaption()
// ----------------
// Set the window caption from file name

void QBrew::setFileCaption(const QString &filename)
{
    setWindowModified(false); // clear modified *

    QString shownname;
    if (filename.isEmpty()) shownname = DEFAULT_FILE;
    else                    shownname = QFileInfo(filename).fileName();

    setWindowTitle(QString("%1 - %2[*]").arg(TITLE).arg(shownname));
}

//////////////////////////////////////////////////////////////////////////////
// querySave()
// -----------
// Ask the user if they want to save their work before going on

int QBrew::querySave()
{
    return QMessageBox::question(this, TITLE + " - Save?",
                                    "<p>Do you wish to save your work first?",
                                    QMessageBox::Yes,
                                    QMessageBox::No,
                                    QMessageBox::Cancel);
}

//////////////////////////////////////////////////////////////////////////////
// queryOverwrite()
// -----------
// Ask the user if they want to overwrite an existing file

int QBrew::queryOverwrite(const QString filename)
{
    return QMessageBox::question(this, TITLE + " - Overwrite?",
                                    QString("<p>Are you sure you want to "
                                            "overwrite the file \"%1\"")
                                    .arg(filename),
                                    QMessageBox::Yes,
                                    QMessageBox::Cancel);
}

//////////////////////////////////////////////////////////////////////////////
// recipeModified()
// ------------------
// Received when recipe is modified

void QBrew::recipeModified()
{
    ui.actionfilesave->setEnabled(true);
    setWindowModified(true);
}

//////////////////////////////////////////////////////////////////////////////
// closeEvent()
// -----------
// Catch the close event

void QBrew::closeEvent(QCloseEvent* e)
{
    if (!recipe_->modified()) {
        e->accept();
    } else {
        // file needs to be saved, what do we do
        switch (querySave()) {
          case QMessageBox::Yes:
              fileSave();
              e->accept();
              break;
          case QMessageBox::Cancel:
              statusBar()->showMessage(READY, 2000);
              e->ignore();
              break;
          case QMessageBox::No:
          default:
              e->accept();
        }
    }
}

//////////////////////////////////////////////////////////////////////////////
// eventFilter()
// -----------
// Filter events

bool QBrew::eventFilter(QObject *obj, QEvent *event) {
    if (event->type() == QEvent::FileOpen) {
        QFileOpenEvent *openevent = static_cast<QFileOpenEvent *>(event);
        fileOpen(openevent->file());
        return true;
    } else {
        // standard event processing
        return QObject::eventFilter(obj, event);
    }
}

//////////////////////////////////////////////////////////////////////////////
// dataBase()
// ---------
// Figure out the base directory for the data

QString QBrew::dataBase()
{
    QString base = qApp->applicationDirPath();

#if defined(Q_WS_X11)
    if (QRegExp("qbrew/?$").indexIn(base) != -1) {
        // we have our own application directory (it ends in 'qbrew')
        base += "/";
    } else if (QRegExp("bin/?$").indexIn(base) != -1) {
        // we are in the bin dir of a filesystem hiearchy like '/usr/local/bin'
        base += "/../share/qbrew/";
    } else {
        // otherwise punt
        base += "/";
    }

#elif defined(Q_WS_MACX)
    if (QRegExp("Contents/MacOS/?$").indexIn(base) != -1) {
        // we're pointing inside an application bundle
        base += "/../Resources/";
    } else {
        // otherwise punt
        base += "/";
    }

#else // Win32 and others
    base += "/";
#endif
    return QDir::cleanPath(base) + "/";
}

//////////////////////////////////////////////////////////////////////////////
// docBase()
// ---------
// Figure out the base directory for the documentation

QString QBrew::docBase()
{
    QString base = qApp->applicationDirPath();

#if defined(Q_WS_X11)
    if (QRegExp("qbrew/?$").indexIn(base) != -1) {
        // we have our own application directory (it ends in 'qbrew')
        base += "/doc/";
    } else if (QRegExp("bin/?$").indexIn(base) != -1) {
        // we are in the bin dir of a filesystem hiearchy like '/usr/local/bin'
        base += "/../share/doc/qbrew/";
    } else {
        // otherwise punt'
        base += "/doc/";
    }

#elif defined(Q_WS_MACX)
    if (QRegExp("Contents/MacOS/?$").indexIn(base) != -1) {
        // we're pointing inside an application bundle
        base += "/../Resources/en.lproj/";
    } else if (QFile::exists(base + "/en.lproj/")) {
        // some other hierarchy using Mac style l10n
        base += "/en.lproj/";
    } else {
        // otherwise punt
        base += "/doc/";
    }

#else // Win32 and others
    base += "/doc/";
#endif
    return QDir::cleanPath(base) + "/";
}

Generated by  Doxygen 1.6.0   Back to index