Logo Search packages:      
Sourcecode: lemonpos version File versions  Download package

lemon.cpp

/***************************************************************************
 *   Copyright (C) 2007-2009 by Miguel Chavez Gamboa                  *
 *   miguel.chavez.gamboa@gmail.com                                        *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *

 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program 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 General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
 ***************************************************************************/

#include "lemon.h"
#include "lemonview.h"
#include "settings.h"

#include <kapplication.h> //MCH: estaba qapplication.h
// #include <qpainter.h>

#include <kdeversion.h>
#include <kglobal.h>
#include <kiconloader.h>
#include <kmenubar.h>
#include <kstatusbar.h>
#include <kconfigdialog.h>
#include <kfiledialog.h>
#include <kactioncollection.h>
#include <kaction.h>
#include <kstandardaction.h>
#include <KLocale>
#include <kstandarddirs.h>
#include <kpassivepopup.h>

#include <ktoolbar.h>


#include <QListWidgetItem>
#include <QPushButton>
#include <QApplication>
#include <QDesktopWidget>
#include <QLabel>
#include <QTimer>
#include <QIcon>
#include <QDateTime>
#include <QDir>
#include <QFileInfoList>
#include <QFileInfo>


//For a frameless window: KMainWindow(0, Qt::FramelessWindowHint)
00060 lemon::lemon()
  : KXmlGuiWindow(0,Qt::FramelessWindowHint),
      m_view(new lemonView(this))
{
    setObjectName(QLatin1String("lemon"));
    setAcceptDrops(false);
    // tell the KMainWindow that this is indeed the main widget
    setCentralWidget(m_view);
    // then, setup our actions
    setupActions();
    // Add typical actions and save size/toolbars/statusbar
    statusBar()->show();
    //add some info labels to status bar
    labelUserInfo = new QLabel("::user::");
    labelDate = new QLabel(" ::Date:: ");
    labelTime = new QLabel(" ::Time:: ");
    labelTransaction = new QLabel("");
    QLabel *imageUser = new QLabel("user");
    QLabel *imageDate = new QLabel("date");
    QLabel *imageTime = new QLabel("time");
    QLabel *imageTransaction = new QLabel("trans");
    imageUser->setPixmap(DesktopIcon("user-identity", 16));
    imageDate->setPixmap(DesktopIcon("view-pim-calendar", 16));
    imageTime->setPixmap(DesktopIcon("chronometer", 16));
    imageTransaction->setPixmap(DesktopIcon("wallet-open", 16));
    updateDate();
    statusBar()->addWidget(imageUser);
    statusBar()->addWidget(labelUserInfo);
    statusBar()->addWidget(imageDate);
    statusBar()->addWidget(labelDate);
    statusBar()->addWidget(imageTime);
    statusBar()->addWidget(labelTime);
    statusBar()->addWidget(imageTransaction);
    statusBar()->addWidget(labelTransaction);
    connect(m_view, SIGNAL(signalLoggedUser()), SLOT(updateUserName()) );
    connect(m_view, SIGNAL(signalNoLoggedUser()), SLOT(updateUserName())  );
    connect(m_view, SIGNAL(signalUpdateClock() ), SLOT(updateClock()) );
    QTimer::singleShot(500, this,  SLOT(hideMenuBar()));

    // apply the saved mainwindow settings, if any, and ask the mainwindow
    // to automatically save settings if changed: window size, toolbar
    // position, icon size, etc.
    setAutoSaveSettings();

    connect(m_view,SIGNAL(signalChangeStatusbar(const QString&)),this,SLOT(changeStatusbar(const QString&)));
    connect(m_view,SIGNAL(signalChangeCaption(const QString&)),this, SLOT(changeCaption(const QString&)));
    connect(m_view, SIGNAL(signalAdminLoggedOn()), this, SLOT(enableConfig()));
    connect(m_view, SIGNAL(signalAdminLoggedOff()), this, SLOT(disableConfig()));
    connect(m_view, SIGNAL(signalNoLoggedUser()), this, SLOT(disableUi()));
    connect(m_view, SIGNAL(signalLoggedUser()), this, SLOT(reactOnLogOn()));
    connect(m_view, SIGNAL(signalStartedOperation()), this, SLOT(reactOnStartedOp()) );
    connect(m_view, SIGNAL(signalUpdateTransactionInfo()), this, SLOT(updateTransaction()));
    connect(m_view, SIGNAL(signalShowProdGrid()), this, SLOT(triggerGridAction()));
    connect(m_view, SIGNAL(signalShowDbConfig()), this, SLOT(showDBConfigDialog()));

    loadStyle();
    disableConfig();
    disableUi();

}

void lemon::triggerGridAction()
{
  QAction *accion = actionCollection()->action("showProductsGrid");
  accion->trigger();
  qDebug()<<"trigger grid action done...";
}

00128 lemon::~lemon()
{
//     delete m_printer;
}

void lemon::setupActions()
{
    KStandardAction::quit(this, SLOT(salir()), actionCollection());
    //KStandardAction::quit(qApp, SLOT(quit()), actionCollection());

    KStandardAction::preferences(this, SLOT(optionsPreferences()), actionCollection());

      //Our actions
    QAction* loginAction =  actionCollection()->addAction( "login" );
    loginAction->setText(i18n("Login"));
    loginAction->setIcon(KIcon("office-address-book")); //identity
    loginAction->setShortcut(Qt::CTRL+Qt::Key_L);
    connect(loginAction, SIGNAL(triggered(bool)),m_view, SLOT(login()));

    QAction *corteCajaAction = actionCollection()->addAction("balance");
    corteCajaAction->setText(i18nc("Account balance", "Balance"));
    corteCajaAction->setIcon(KIcon("lemon-balance"));
    corteCajaAction->setShortcut(Qt::CTRL+Qt::Key_B);
    connect(corteCajaAction, SIGNAL(triggered(bool)), m_view, SLOT(corteDeCaja()));

    QAction* enterCodeAction = actionCollection()->addAction( "enterCode" );
    enterCodeAction->setText(i18n("Enter Code"));
    enterCodeAction->setIcon(KIcon("lemon-tag"));
    enterCodeAction->setShortcut(Qt::Key_F2);
    connect(enterCodeAction, SIGNAL(triggered(bool)),m_view, SLOT(showEnterCodeWidget()));

    QAction* searchItemAction = actionCollection()->addAction( "searchItem" );
    searchItemAction->setText(i18n("Search Item"));
    searchItemAction->setIcon(KIcon("edit-find"));
    searchItemAction->setShortcut(Qt::Key_F3);
    connect(searchItemAction, SIGNAL(triggered(bool)),m_view, SLOT(showSearchItemWidget()));

    QAction* delSelectedItemAction = actionCollection()->addAction( "deleteSelectedItem" );
    delSelectedItemAction->setText(i18n("Delete Selected Item"));
    delSelectedItemAction->setIcon(KIcon("lemon-boxcancel"));
    delSelectedItemAction->setShortcut(Qt::Key_Delete);
    connect(delSelectedItemAction, SIGNAL(triggered(bool)),m_view, SLOT(deleteSelectedItem()));

    QAction* finishTransactionAction = actionCollection()->addAction( "finishTransaction" );
    finishTransactionAction->setText(i18n("Finish transaction"));
    finishTransactionAction->setIcon(KIcon("lemon-transaction-accept"));
    finishTransactionAction->setShortcut(Qt::Key_F8);
    connect(finishTransactionAction, SIGNAL(triggered(bool)),m_view, SLOT(finishCurrentTransaction()));

    QAction* cancelTransactionAction = actionCollection()->addAction( "cancelTransaction" );
    cancelTransactionAction->setText(i18n("Cancel transaction"));
    cancelTransactionAction->setIcon(KIcon("lemon-transaction-cancel"));
    cancelTransactionAction->setShortcut(Qt::Key_F9);
    connect(cancelTransactionAction, SIGNAL(triggered(bool)),m_view, SLOT(preCancelCurrentTransaction()));

    QAction* cancelSellAction = actionCollection()->addAction("cancelTicket");
    cancelSellAction->setText(i18n("Cancel a ticket"));
    cancelSellAction->setIcon(KIcon("lemon-ticket-cancel") );
    cancelSellAction->setShortcut(Qt::Key_F10);
    connect(cancelSellAction, SIGNAL(triggered(bool)),m_view, SLOT(askForIdToCancel()));

       //NOTE: This action is for setting how much money is on the drawer...
    QAction* startOperationAction = actionCollection()->addAction( "startOperation" );
    startOperationAction->setText(i18n("Start Operation"));
    startOperationAction->setIcon(KIcon("window-new"));
    startOperationAction->setShortcut(Qt::Key_F11);
    connect(startOperationAction, SIGNAL(triggered(bool)),m_view, SLOT(startOperation()));

    QAction *payFocusAction = actionCollection()->addAction("payFocus");
    payFocusAction->setText(i18n("Pay focus"));
    payFocusAction->setIcon(KIcon("lemon-payfocus"));
    payFocusAction->setShortcut(Qt::Key_Alt + Qt::Key_End); //Conflicts with the editLine's own shortcut...
    connect(payFocusAction, SIGNAL(triggered(bool)),m_view, SLOT(focusPayInput()));

    QAction *showProdGridAction = actionCollection()->addAction("showProductsGrid");
    showProdGridAction->setCheckable(true);
    showProdGridAction->setText(i18n("Show/Hide Products Grid"));
    showProdGridAction->setIcon(KIcon("view-split-top-bottom"));
    showProdGridAction->setShortcut(Qt::Key_Control+Qt::Key_G);
    connect(showProdGridAction, SIGNAL(toggled(bool)), m_view, SLOT(showProductsGrid(bool)));

    QAction *showPriceCheckerAction = actionCollection()->addAction("showPriceChecker");
    showPriceCheckerAction->setText(i18n("Show Price Checker"));
    showPriceCheckerAction->setIcon(KIcon("lemon-price-checker"));
    showPriceCheckerAction->setShortcut(Qt::Key_F4);
    connect(showPriceCheckerAction, SIGNAL(triggered(bool)), m_view, SLOT(showPriceChecker()));

    QAction *reprintTicketAction = actionCollection()->addAction("reprintTicket");
    reprintTicketAction->setText(i18n("Reprint ticket"));
    reprintTicketAction->setIcon(KIcon("lemon-print-ticket"));
    reprintTicketAction->setShortcut(Qt::Key_F5);
    connect(reprintTicketAction, SIGNAL(triggered(bool)), m_view, SLOT(showReprintTicket()));

    QAction *cashOutAction = actionCollection()->addAction("cashOut");
    cashOutAction->setText(i18n("Cash Out"));
    cashOutAction->setIcon(KIcon("lemon-cashout"));
    cashOutAction->setShortcut(Qt::Key_F6);
    connect(cashOutAction, SIGNAL(triggered(bool)), m_view, SLOT(cashOut()));

    setupGUI();

    setGeometry(QApplication::desktop()->screenGeometry(this));
    if (!Settings::splitterSizes().isEmpty()) m_view->setTheSplitterSizes(Settings::splitterSizes());
}

00233 void lemon::saveProperties(KConfigGroup &config)
{
    // the 'config' object points to the session managed
    // config file.  anything you write here will be available
    // later when this app is restored

    //if (!m_view->currentURL().isNull()) {
    //    config.writePathEntry("lastURL", m_view->currentURL());
    //}
}

00244 void lemon::readProperties(const KConfigGroup &config)
{
    // the 'config' object points to the session managed
    // config file.  this function is automatically called whenever
    // the app is being restored.  read in here whatever you wrote
    // in 'saveProperties'

    //QString url = config.readPathEntry("lastURL", QString());

}


void lemon::loadStyle()
{
//   QString defaultStyle = QApplication::style()->metaObject()->className();
//   qDebug()<<"Default Style:"<<defaultStyle;
//   qDebug()<<"QStyles Available:"<<QStyleFactory::keys();
//     //qApp->setStyle("Plastik");
//   defaultStyle = QApplication::style()->metaObject()->className();
//   qDebug()<<"Style used:"<<defaultStyle;

  qDebug()<<"Loading Stylesheet...";
  if (Settings::useStyle()) {
    QString fileName; QString path;
    path = KStandardDirs::locate("appdata", "styles/");
    fileName = path + Settings::styleName() + "/" + Settings::styleName() + ".qss";
    QFile file(fileName);
    bool op = file.open(QFile::ReadOnly);
    QString styleSheet = QLatin1String(file.readAll());
    //replace fakepath to the real path..
    QString finalStyle = styleSheet.replace("[STYLE_PATH]", path + Settings::styleName() + "/");
    qApp->setStyleSheet(finalStyle);
    if (op) file.close();
  }
  else {
    //Load a simple style...
    QString fileName; QString path;
    path = KStandardDirs::locate("appdata", "styles/");
    fileName = path + Settings::styleName() + "/simple.qss";
    QFile file(fileName);
    bool op = file.open(QFile::ReadOnly);
    QString styleSheet = QLatin1String(file.readAll());
    //replace fakepath to the real path..
    QString finalStyle = styleSheet.replace("[STYLE_PATH]", path + Settings::styleName() + "/");
    qApp->setStyleSheet(finalStyle);
    if (op) file.close();
  }
  showToolBars();
}


/**This is used to get Database user,password,server to set initial config, in case the db server is remote.
   So we show the config dialog, and when saved login again. It is called from main_view.login()
**/
00298 void lemon::showDBConfigDialog()
{
  //avoid to have 2 dialogs shown
  if ( KConfigDialog::showDialog( "settings" ) )  {
    return;
  }
  KConfigDialog *dialog = new KConfigDialog(this, "settings", Settings::self());

  QWidget *dbSettingsDlg = new QWidget;
  ui_prefs_db.setupUi(dbSettingsDlg);
  dialog->addPage(dbSettingsDlg, i18n("Database"), "kexi"); // book
  connect(dialog, SIGNAL(settingsChanged(QString)), m_view, SLOT(settingsChangedOnInitConfig()));
  dialog->setAttribute( Qt::WA_DeleteOnClose );
  dialog->show();

  qDebug()<<"CONFIG DIALOG SHOWN... - showDBConfigDialog()";
}

00316 void lemon::optionsPreferences()
{
    //avoid to have 2 dialogs shown
    if ( KConfigDialog::showDialog( "settings" ) )  {
        return;
    }
    KConfigDialog *dialog = new KConfigDialog(this, "settings", Settings::self());

    QWidget *generalSettingsDlg = new QWidget;
    ui_prefs_base.setupUi(generalSettingsDlg);
    dialog->addPage(generalSettingsDlg, i18n("General"), "configure");

    QWidget *storeDataSettingsDlg = new QWidget;
    ui_store_data.setupUi(storeDataSettingsDlg);
   //NOTE: What icon to use for this??
    dialog->addPage(storeDataSettingsDlg, i18n("Store"), "go-home");

    QWidget *dbSettingsDlg = new QWidget;
    ui_prefs_db.setupUi(dbSettingsDlg);
    dialog->addPage(dbSettingsDlg, i18n("Database"), "kexi"); // book

    QWidget *styleSettingsDlg = new QWidget;
    ui_pref_style.setupUi(styleSettingsDlg);
    dialog->addPage(styleSettingsDlg, i18n("Appearence"), "draw-brush");
    lemon::populateStyleList();
    connect(ui_pref_style.styleList, SIGNAL(itemClicked(QListWidgetItem *)), SLOT(sLitemActivated(QListWidgetItem *)) );
    connect(ui_pref_style.styleList, SIGNAL(itemActivated(QListWidgetItem *)), SLOT(sLitemActivated(QListWidgetItem *)) );

    QWidget *securitySettingsDlg = new QWidget;
    ui_pref_security.setupUi(securitySettingsDlg);
    dialog->addPage(securitySettingsDlg, i18n("Security"), "dialog-password");

    QWidget *printersSettingDlg = new QWidget;
    ui_pref_printers.setupUi(printersSettingDlg);
    dialog->addPage(printersSettingDlg, i18n("Printer"), "lemon-printer");

    connect(dialog, SIGNAL(settingsChanged(QString)), m_view, SLOT(settingsChanged()));
    connect(dialog, SIGNAL(settingsChanged(const QString &)), this, SLOT(loadStyle()));
    //free mem by deleting the dialog on close without waiting for deletingit when the application quits
    dialog->setAttribute( Qt::WA_DeleteOnClose );
    dialog->show();
}


00360 void lemon::hideToolBars()
{
  QList<KToolBar*> tb  = toolBars();
  for (int i=0; i < tb.count(); i++)
    tb.at(i)->hide();
}

void lemon::showToolBars()
{
  QList<KToolBar*> tb  = toolBars();
  for (int i=0; i < tb.count(); i++)
    tb.at(i)->show();
}

00374 void lemon::hideMenuBar()
{
  if (!menuBar()->isHidden()) {
    menuBar()->hide();
  }
}

void lemon::reactOnStartedOp()
{
  if (m_view->canStartSelling()) {
    enableUi();
    //disableStartOp();
  }
  else {
    disableUi();
    //enableStartOp();
  }
}


00394 void lemon::reactOnLogOn()
{
 QString msg = i18n("Administrator needs to start operation before you can start selling...");
  if (m_view->canStartSelling())
    enableUi();
  else {
    disableUi();
    //Show a dialog saying that operations need to be started by admin ???
    if (m_view->getLoggedUser() !="admin")
      KPassivePopup::message( i18n("Warning:"),msg,
                              DesktopIcon("dialog-warning", 48), this );
  }
}

00408 void lemon::disableUi()
{
  m_view->setDisabled(true);
  QAction *action = actionCollection()->action("enterCode");
  action->setDisabled(true);
  action = actionCollection()->action("startOperation");
  action->setDisabled(true);
  action = actionCollection()->action("searchItem");
  action->setDisabled(true);
  action = actionCollection()->action("deleteSelectedItem");
  action->setDisabled(true);
  action = actionCollection()->action("finishTransaction");
  action->setDisabled(true);
  action = actionCollection()->action("cancelTransaction");
  action->setDisabled(true);
  action = actionCollection()->action("balance");
  action->setDisabled(true);
  action = actionCollection()->action("payFocus");
  action->setDisabled(true);
  action = actionCollection()->action("cancelTicket");
  action->setDisabled(true);
  action = actionCollection()->action("showProductsGrid");
  action->setDisabled(true);
  action = actionCollection()->action("login");
  action->setEnabled(true); //enable login!
  
  disableConfig();
}

00437 void lemon::enableUi()
{
  m_view->setEnabled(true);
  QAction *action = actionCollection()->action("enterCode");
  action->setEnabled(true);
  action = actionCollection()->action("startOperation");
  action->setDisabled(true);
  action = actionCollection()->action("searchItem");
  action->setEnabled(true);
  action = actionCollection()->action("deleteSelectedItem");
  action->setEnabled(true);
  action = actionCollection()->action("finishTransaction");
  action->setEnabled(true);
  action = actionCollection()->action("cancelTransaction");
  action->setEnabled(true);
  action = actionCollection()->action("balance");
  action->setEnabled(true);
  action = actionCollection()->action("payFocus");
  action->setEnabled(true);
  action = actionCollection()->action("cancelTicket");
  action->setEnabled(true);
  action = actionCollection()->action("showProductsGrid");
  action->setEnabled(true);
}

00462 void lemon::disableConfig()
{
  QAction *actPref = actionCollection()->action(KStandardAction::stdName(KStandardAction::Preferences));
  actPref->setDisabled(true);
  QAction *actQuit = actionCollection()->action(KStandardAction::stdName(KStandardAction::Quit));
  //FIXME: esto no es muy bueno en produccion..
  if (!Settings::allowAnyUserToQuit()) actQuit->setDisabled(true);
}

00471 void lemon::enableConfig()
{
  QAction *actPref = actionCollection()->action(KStandardAction::stdName(KStandardAction::Preferences));
  actPref->setEnabled(true);
  QAction *actQuit = actionCollection()->action(KStandardAction::stdName(KStandardAction::Quit));
  actQuit->setEnabled(true);

  QAction *actSop = actionCollection()->action("startOperation");
  actSop->setEnabled(true);
}


00483 void lemon::populateStyleList()
{
  QString path = KStandardDirs::locate("appdata", "styles/");
  QDir dir(path);
  dir.setFilter(QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot);
  dir.setSorting(QDir::Name | QDir::LocaleAware);
  QFileInfoList list = dir.entryInfoList();
  for (int i = 0; i < list.size(); ++i) {
    QFileInfo fileInfo = list.at(i);
    ui_pref_style.styleList->addItem(fileInfo.fileName());
  }
  //Select the style used...
  QList<QListWidgetItem *> itemLfound = ui_pref_style.styleList->findItems(Settings::styleName(), Qt::MatchExactly);
  if (itemLfound.count() == 1) {
    QListWidgetItem *item = itemLfound.first();
    ui_pref_style.styleList->setCurrentItem(item);
  }
}

00502 void lemon::sLitemActivated(QListWidgetItem * item)
{
  ui_pref_style.kcfg_styleName->setText(item->text());
}


00508 void lemon::updateClock()
{
  QTime time = QTime::currentTime();
  QString text = time.toString("hh:mm");
  if ((time.second() % 2) == 0)
    text[2] = '.';
  labelTime->setText(text);
  if ((time.hour()==0) && (time.minute()==0) && (time.second()==0) ) updateDate();
}

00518 void lemon::updateDate()
{
  QDate dt = QDate::currentDate();
  labelDate->setText(KGlobal::locale()->formatDate(dt));
}

00524 void lemon::updateUserName()
{
  labelUserInfo->setText(m_view->getLoggedUser());
}

00529 void lemon::updateTransaction()
{
  QString tn = m_view->getCurrentTransactionString();
  labelTransaction->setText(i18n("Transaction #%1", tn));
}



00537 void lemon::changeStatusbar(const QString& text)
{
    // display the text on the statusbar
  statusBar()->showMessage(text, 1500);
}

00543 void lemon::changeCaption(const QString& text)
{
    // display the text on the caption
  setCaption(text);
}

//FIXME: Verificar que las transacciones se cancelen y se guarden las completadas y se guarde el corte de caja.
bool lemon::queryClose()
{
  Settings::setSplitterSizes(m_view->getTheSplitterSizes());
  //FIXED Settings::writeConfig();
  Settings::self()->writeConfig();
  //Close only by admin user. or ask for password??
  if (Settings::allowAnyUserToQuit())
  {
    bool reallyQuit=false;
    if (m_view->getLoggedUser() == "admin") reallyQuit=true;  else reallyQuit = m_view->validAdminUser();
    //cancel current transaction
    if (m_view->isTransactionInProgress()){  m_view->cancelByExit(); qDebug()<<"Cancelled on queryClose";}
    //save balance
    m_view->saveBalance();
    return reallyQuit;
  }
  else if ( m_view->getLoggedUser() == "admin" ) {
    //cancel current transaction
    if (m_view->isTransactionInProgress()){  m_view->cancelByExit(); qDebug()<<"Cancelled on queryClose";}
    //save balance
    m_view->saveBalance();
    return true;
  } else return false;
}

00575 void lemon::salir()
{
  if (queryClose()) kapp->quit();
}

#include "lemon.moc"

Generated by  Doxygen 1.6.0   Back to index