diff options
Diffstat (limited to 'kmymoney2/widgets/kmymoneywizard.h')
-rw-r--r-- | kmymoney2/widgets/kmymoneywizard.h | 539 |
1 files changed, 539 insertions, 0 deletions
diff --git a/kmymoney2/widgets/kmymoneywizard.h b/kmymoney2/widgets/kmymoneywizard.h new file mode 100644 index 0000000..21b57b4 --- /dev/null +++ b/kmymoney2/widgets/kmymoneywizard.h @@ -0,0 +1,539 @@ +/*************************************************************************** + kmymoneywizard.h + ------------------- + copyright : (C) 2006 by Thomas Baumagrt + email : ipwizard@users.sourceforge.net + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef KMYMONEYWIZARD_H +#define KMYMONEYWIZARD_H + +// ---------------------------------------------------------------------------- +// QT Includes + +#include <qdialog.h> +#include <qvaluelist.h> +#include <qpalette.h> +class QVBoxLayout; +class QHBoxLayout; +class QLabel; +class QFrame; + +// ---------------------------------------------------------------------------- +// KDE Includes + +class KPushButton; + +// ---------------------------------------------------------------------------- +// Project Includes + +class KMyMoneyTitleLabel; +class KMyMoneyWizard; +class KMyMoneyWizardPagePrivate; +class kMandatoryFieldGroup; + +/** + * @author Thomas Baumgart (C) 2006 + * + * @note: the following documentation is somewhat outdated + * as of May 2007. Wizards should use a namespace + * for the pages and can use the WizardPage<T> template class. + * See the NewUserWizard class and NewUserWizardPages namespace + * as an example of this setup. + * + * This class represents the base class for wizard pages for the + * KMyMoneyWizard. One cannot create a wizard page directly, but + * must derive from it. The KMyMoneyWizardPage class provides the + * necessary functionality to work in concert with KMyMoneyWizard. + * + * Therefore, few steps are necessary to use this class. They seem to + * be awkward at some stage, but I wanted to be able to use Qt designer + * to actually design the widget for the page. That's why some things + * aren't implemented in a more straight fashion than one would + * normally do this. + * + * The first step is to derive a specific base page for the specific wizard. + * In this example we use the name NewUser as template for the specific wizard. + * This class provides a 'back'-pointer to the actual wizard object + * for all pages. + * + * @code + * class KNewUserPage : public KMyMoneyWizardPage + * { + * public: + * KNewUserPage(unsigned int step, QWidget* widget, KNewUserWizard* parent, const char* name); + * + * protected: + * KNewUserWizard* m_wizard; + * } + * @endcode + * + * The implementation of this class is rather straight-forward: + * + * @code + * KNewUserPage::KNewUserPage(unsigned int step, QWidget* widget, KNewUserWizard* parent, const char* name) : + * KMyMoneyWizardPage(step, widget, name), + * m_wizard(parent) + * { + * } + * @endcode + * + * For each page of the wizard, you will have to create a @p ui file with + * Qt designer. + * Let's assume we call the first page of the wizard 'General' and go + * from there. + * We also assume, that the wizard has more than one page. + * The ui designer generated class should have the name KNewUserGeneralDecl + * as all other dialogs. The class definition of KNewUserGeneral will + * look like this: + * + * @code + * class KNewUserGeneral : public KNewUserGeneralDecl, public KNewUserPage + * { + * Q_OBJECT + * public: + * KNewUserGeneral(KNewUserWizard* parent, const char* name = 0); + * KMyMoneyWizardPage* nextPage(void); + * bool isLastPage(void) { return false; } + * + * protected: + * KNewUserWizard* m_wizard; + * } + * @endcode + * + * The implementation depends heavily on the logic of your code. If you only + * fill some widgets, it could be as simple as: + * + * @code + * KNewUserGeneral::KNewUserGeneral(KNewUserWizard* parent, const char* name) : + * KNewUserGeneralDecl(parent), + * KNewUserPage(1, this, parent, name) + * { + * kMandatoryFieldGroup* mandatoryGroup = new kMandatoryFieldGroup(this); + * mandatoryGroup->add(m_userName); + * connect(m_mandatoryGroup, SIGNAL(stateChanged()), object(), SIGNAL(completeStateChanged())); + * } + * + * KMyMoneyWizardPage* KNewUserGeneral::nextPage(void) + * { + * return m_wizard->m_personalPage; + * } + * @endcode + * + * A note on the first parameter to KNewUserPage in the above example: it ties + * this page to be part of step 1 (see KMyMoneyWizard::addStep() for details). + * + * Depending on the actual logic of the page, you would want to override the + * following methods: resetPage, nextPage, isLastPage and isComplete. + * + * @note The implementation of this class is heavily based on ideas found at + * http://doc.trolltech.com/4.1/dialogs-complexwizard.html + */ +class KMyMoneyWizardPage +{ +public: + /** + * This method is called by the wizard when the page is entered from + * the previous page. The default implementation does nothing. + */ + virtual void enterPage(void); + + /** + * This method is called by the wizard when the page is left to return to + * the previous page. The default implementation does nothing. + */ + virtual void leavePage(void); + + /** + * This method is called by the wizard whenever a page is entered + * (either in forward or backward direction). The default + * implementation does nothing. + */ + virtual void resetPage(void); + + /** + * This method returns a pointer to the next page that should be + * shown when the user presses the 'Next' button. + * + * @return pointer to next wizard page + */ + virtual KMyMoneyWizardPage* nextPage(void) const; + + /** + * This returns, if the current page is the last page of the wizard. + * The default implementation returns @p false if nextPage() returns 0, + * @p true otherwise. + * + * @retval false more pages follow + * @retval true this is the last page of the wizard + */ + virtual bool isLastPage(void) const; + + /** + * This returns, if all necessary data for this page has been + * filled. It is used to enabled the 'Next' or 'Finish' button. + * The button is only enabled, if this method returns @p true, + * which is the default implementation. + * + * @retval false more data required from the user before we can proceed + * @retval true all data available, we allow to switch to the next page + */ + virtual bool isComplete(void) const; + + /** + * This method returns the step to which this page belongs. + * It is required by the KMyMoneyWizard and is not intended + * to be used by application code. + * + * @return step of wizard this page belongs to + */ + unsigned int step(void) const { return m_step; } + + /** + * This method returns a pointer to the widget of the page. + * It is required by the KMyMoneyWizard and is not intended + * to be used by application code. + * + * @return pointer to widget of page + */ + QWidget* widget(void) const { return m_widget; } + + /** + * This method returns a pointer to the QObject used for + * the signal/slot mechanism. + * It is required by the KMyMoneyWizard and can be used + * by application code for signal/slot connections as well. + * Other use is not foreseen. + */ + QObject* object(void) const; + + /** + * This method returns a pointer to the widget which should + * receive the focus when the page is opened. + * + * @return pointer to widget or 0 if none is to be selected + * The default implementation returns 0 + */ + virtual QWidget* initialFocusWidget(void) const { return 0; } + + virtual KMyMoneyWizard* wizard(void) const = 0; + + /** + * This method returns a specific help context for the page shown + * The default returns an empty string. + */ + virtual const QString& helpContext(void) const; + + virtual ~KMyMoneyWizardPage() {} +protected: + /** + * Constructor (kept protected, so that one cannot create such an object directly) + */ + KMyMoneyWizardPage(unsigned int step, QWidget* widget, const char* name = 0); + + /** + * This method must be called by the implementation when the + * data in the fields of the wizard change and the state of + * completeness changed. + * + * @note If you do not override isComplete() then there is no need + * to call this method. + */ + void completeStateChanged(void) const; + +protected: + kMandatoryFieldGroup* m_mandatoryGroup; + +private: + unsigned int m_step; + QWidget* m_widget; + KMyMoneyWizardPagePrivate* const d; +}; + + +/** + * The general base class for wizard pages + * + * @author Thomas Baumgart + */ +template <class T> + class WizardPage : public KMyMoneyWizardPage +{ +public: + WizardPage(unsigned int step, QWidget* widget, T* parent, const char* name) : + KMyMoneyWizardPage(step, widget, name), + m_wizard(parent), + m_wizardBase(parent) + { + } + virtual ~WizardPage() {} + virtual KMyMoneyWizard* wizard(void) const { return m_wizardBase; } + +protected: + T* m_wizard; + KMyMoneyWizard* m_wizardBase; +}; + + +/** + * @author Thomas Baumgart (C) 2006 + * + * This is a base class for implementation of the KMyMoneyWizard. It provides + * the following layout of a wizard: + * + * @code + * +-wizardLayout-----------------------------------------------+ + * | | + * +------------------------------------------------------------+ + * |+-stepLayout--++-------------------------------------------+| + * || ||+-pageLayout------------------------------+|| + * || ||| ||| + * || ||| ||| + * || ||| ||| + * || ||| ||| + * || ||| ||| + * || ||| ||| + * || ||+-----------------------------------------+|| + * || |||+-buttonLayout--------------------------+||| + * || |||| |||| + * || |||+---------------------------------------+||| + * || ||+-----------------------------------------+|| + * |+-------------++-------------------------------------------+| + * +------------------------------------------------------------+ + * @endcode + * + * The top bar is filled with a KMyMoneyTitleLabel as known from + * KMyMoney's views. To the left there is an area in the same color + * as the title bar showing the steps for this wizard. Each such step + * can consist of one or more wizard pages. At the bottom of this area + * the text "Step x of y" is shown and updated. To the right of this + * part, the actual wizard page is shown. At the bottom of the page + * the class inserts a standard button widget consisting of a Help, + * Back, Next/Finish and Cancel button. + * + * The wizard serves as container for the wizard pages. In order to access + * the data filled into the pages, one would have to provide getter methods. + * + * Here is an example how this object could be used. Please also see the + * example described with the KMyMoneyWizardPage class. + * + * @code + * + * class KNewUserGeneral; + * class KNewUserPersonal; + * + * class KNewUserWizard : public KMyMoneyWizard + * { + * Q_OBJECT + * public: + * KNewUserWizard(QWidget* parent = 0, const char* name = 0, bool modal = false, WFlags flags = 0); + * + * private: + * KNewUserGeneral* m_generalPage; + * KNewUserPersonal* m_personalPage; + * KNewUserFinal* m_finalPage; + * // add more pages here + * + * friend class KNewUserGeneral; + * friend class KNewUserPersonal; + * friend class KNewUserFinal; + * // add more pages here + * }; + * @endcode + * + * The implementation is also easy and looks like this: + * + * @code + * KNewUserWizard::KNewUserWizard(QWidget* parent, const char* name, bool modal, WFlags flags) : + * KMyMoneyWizard(parent, name, modal, flags) + * { + * setTitle("KMyMoney New User Setup"); + * addStep("General Data"); + * addStep("Personal Data"); + * addStep("Finish"); + * + * m_generalPage = new KNewUserGeneral(this); + * m_personalPage = new KNewUserPersonal(this); + * m_finalPage = new KNewUserFinal(this); + * + * setFirstPage(m_testPage1); + * } + * @endcode + * + * Don't forget to call setFirstPage() to get things started. + * + * The code to use this whole structure would then look something like this: + * + * @code + * KNewUserWizard* wizard = new KNewUserWizard(this, "NewUserWizard"); + * int rc = wizard->exec(); + * @endcode + * + * The return code of exec() is either @p QDialog::Accepted or + * @p QDialog::Rejected. + * + * @note The implementation of this class is heavily based on ideas found at + * http://doc.trolltech.com/4.1/dialogs-complexwizard.html + */ +class KMyMoneyWizard : public QDialog +{ + friend class KMyMoneyWizardPage; + + Q_OBJECT +public: + /** + * Modify the title of the wizard to be @p txt. + * + * @param txt The text that should be used as title + */ + void setTitle(const QString& txt); + + /** + * Add step @p text to the wizard + * + * @param text Text to be shown for this step + */ + void addStep(const QString& text); + + QValueList<KMyMoneyWizardPage*> historyPages(void) const { return m_history; } + + /** + * This method repeats selection of the current step in the + * step frame. + * This is used to allow changes made to showing and hiding + * pages to immediately to be reflected in the step frame + */ + void reselectStep(void); + + /** + * Setup a global help context for the wizard. It will be used whenever + * there is no specific help context available for the current page. + * + * @sa KMyMoneyWizardPage::helpContext() + */ + void setHelpContext(const QString& ctx) { m_helpContext = ctx; } + + virtual ~KMyMoneyWizard(){} + +signals: + /** + * This signal is sent out, when a new payee needs to be created + * @sa KMyMoneyCombo::createItem() + * + * @param txt The name of the payee to be created + * @param id A connected slot should store the id of the created object in this variable + */ + void createPayee(const QString& txt, QString& id); + + /** + * This signal is sent out, when a new category needs to be created + * @sa KMyMoneyCombo::createItem() + * + * @param txt The name of the category to be created + * @param id A connected slot should store the id of the created object in this variable + */ + void createCategory(const QString& txt, QString& id); + +protected: + /** + * Constructor (kept protected, so that one cannot create such an object directly) + */ + KMyMoneyWizard(QWidget *parent = 0, const char *name = 0, bool modal = false, WFlags f = 0); + + /** + * This method sets up the first page after creation of the object + * + * @param page pointer to first page of wizard + */ + void setFirstPage(KMyMoneyWizardPage* page); + + /** + * This method allows to hide or show a @p step. + * + * @param step step to be shown/hidden + * @param hidden hide step if true (the default) or show it if false + */ + void setStepHidden(unsigned int step, bool hidden = true); + +protected slots: + virtual void accept(void); + void completeStateChanged(void); + +private: + void updateStepCount(void); + +private slots: + void backButtonClicked(void); + void nextButtonClicked(void); + void helpButtonClicked(void); + +protected: + /* + * The buttons + */ + KPushButton* m_cancelButton; + KPushButton* m_backButton; + KPushButton* m_nextButton; + KPushButton* m_finishButton; + KPushButton* m_helpButton; + +private: + /** + * Switch to page which is currently the top of the history stack. + * @p oldPage is a pointer to the current page or 0 if no page + * is shown. + * + * @param oldPage pointer to currently displayed page + */ + void switchPage(KMyMoneyWizardPage* oldPage); + + /** + * This method selects the step given by @p step. + * + * @param step step to be selected + */ + void selectStep(unsigned int step); + + /* + * The layouts + */ + QVBoxLayout* m_wizardLayout; + QVBoxLayout* m_stepLayout; + QVBoxLayout* m_pageLayout; + QHBoxLayout* m_buttonLayout; + + /* + * Some misc. widgets required + */ + QFrame* m_stepFrame; + QLabel* m_stepLabel; + QPalette m_stepPalette; + + QValueList<QLabel*> m_steps; // the list of step labels + int m_step; // the currently selected step + + /* + * The title bar + */ + KMyMoneyTitleLabel* m_titleLabel; + + /* + * The history stack + */ + QValueList<KMyMoneyWizardPage*> m_history; + + QString m_helpContext; +}; + + + +#endif |