33 #include <config-kleopatra.h>
43 #include <KPushButton>
44 #include <KStandardGuiItem>
46 #include <QDialogButtonBox>
49 #include <QStackedWidget>
51 #include <QVBoxLayout>
63 using namespace Kleo::Crypto::Gui;
65 class Wizard::Private {
66 friend class ::Wizard;
69 explicit Private(
Wizard * qq );
72 void updateButtonStates();
73 bool isLastPage(
int id )
const;
74 int previousPage()
const;
78 std::vector<int> pageOrder;
79 std::set<int> hiddenPages;
80 std::map<int, WizardPage*> idToPage;
82 QStackedWidget* stack;
83 KPushButton* nextButton;
84 QPushButton* backButton;
85 QPushButton* cancelButton;
90 QLabel* subTitleLabel;
91 QFrame* explanationFrame;
92 QLabel* explanationLabel;
93 QTimer* nextPageTimer;
97 Wizard::Private::Private(
Wizard * qq )
98 :
q( qq ), currentId( -1 ), stack( new QStackedWidget )
100 nextPageTimer =
new QTimer(
q );
101 nextPageTimer->setInterval( 0 );
102 connect( nextPageTimer, SIGNAL(timeout()),
q, SLOT(next()) );
103 nextItem = KGuiItem( i18n(
"&Next" ) );
104 finishItem = KStandardGuiItem::ok();
105 QVBoxLayout *
const top =
new QVBoxLayout(
q );
107 titleFrame =
new QFrame;
108 titleFrame->setFrameShape( QFrame::StyledPanel );
109 titleFrame->setAutoFillBackground(
true );
110 titleFrame->setBackgroundRole( QPalette::Base );
111 QVBoxLayout*
const titleLayout =
new QVBoxLayout( titleFrame );
112 titleLabel =
new QLabel;
113 titleLayout->addWidget( titleLabel );
114 subTitleLabel =
new QLabel;
115 subTitleLabel->setWordWrap(
true );
116 titleLayout->addWidget( subTitleLabel );
117 top->addWidget( titleFrame );
118 titleFrame->setVisible(
false );
120 top->addWidget( stack );
122 explanationFrame =
new QFrame;
123 explanationFrame->setFrameShape( QFrame::StyledPanel );
124 explanationFrame->setAutoFillBackground(
true );
125 explanationFrame->setBackgroundRole( QPalette::Base );
126 QVBoxLayout*
const explanationLayout =
new QVBoxLayout( explanationFrame );
127 explanationLabel =
new QLabel;
128 explanationLabel->setWordWrap(
true );
129 explanationLayout->addWidget( explanationLabel );
130 top->addWidget( explanationFrame );
131 explanationFrame->setVisible(
false );
134 QHBoxLayout* buttonLayout =
new QHBoxLayout( buttonWidget );
135 QDialogButtonBox *
const box =
new QDialogButtonBox;
137 cancelButton = box->addButton( QDialogButtonBox::Cancel );
138 q->connect( cancelButton, SIGNAL(clicked()),
q, SLOT(reject()) );
140 backButton =
new QPushButton;
141 backButton->setText( i18n(
"Back" ) );
142 q->connect( backButton, SIGNAL(clicked()),
q, SLOT(back()) );
143 box->addButton( backButton, QDialogButtonBox::ActionRole );
145 nextButton =
new KPushButton;
146 nextButton->setGuiItem( nextItem );
147 q->connect( nextButton, SIGNAL(clicked()),
q, SLOT(next()) );
148 box->addButton( nextButton, QDialogButtonBox::ActionRole );
149 buttonLayout->addWidget( box );
151 top->addWidget( buttonWidget );
153 q->connect(
q, SIGNAL(rejected()),
q, SIGNAL(canceled()) );
156 Wizard::Private::~Private() { kDebug(); }
160 bool Wizard::Private::isLastPage(
int id )
const
162 return !pageOrder.empty() ? pageOrder.back() ==
id :
false;
165 void Wizard::Private::updateButtonStates()
167 const bool isLast = isLastPage( currentId );
168 const bool canGoToNext =
q->canGoToNextPage();
171 if ( customNext.text().isEmpty() && customNext.icon().isNull() )
172 nextButton->setGuiItem( isLast ? finishItem : nextItem );
174 nextButton->setGuiItem( customNext );
175 nextButton->setEnabled( canGoToNext );
176 cancelButton->setEnabled( !isLast || !canGoToNext );
177 backButton->setEnabled(
q->canGoToPreviousPage() );
179 nextPageTimer->start();
182 void Wizard::Private::updateHeader()
185 assert( !widget || stack->indexOf( widget ) != -1 );
187 stack->setCurrentWidget( widget );
188 const QString title = widget ? widget->
title() : QString();
189 const QString subTitle = widget ? widget->
subTitle() : QString();
190 const QString explanation = widget ? widget->
explanation() : QString();
191 titleFrame->setVisible( !title.isEmpty() || !subTitle.isEmpty() || !explanation.isEmpty() );
192 titleLabel->setVisible( !title.isEmpty() );
193 titleLabel->setText( title );
194 subTitleLabel->setText( subTitle );
195 subTitleLabel->setVisible( !subTitle.isEmpty() );
196 explanationFrame->setVisible( !explanation.isEmpty() );
197 explanationLabel->setVisible( !explanation.isEmpty() );
198 explanationLabel->setText( explanation );
199 q->resize(
q->sizeHint().expandedTo(
q->size() ) );
202 Wizard::Wizard(
QWidget * parent, Qt::WindowFlags f )
203 :
QDialog( parent, f ),
d( new Private( this ) )
213 kleo_assert( d->idToPage.find(
id ) == d->idToPage.end() );
214 d->idToPage[id] = widget;
215 d->stack->addWidget( widget );
216 connect( widget, SIGNAL(completeChanged()),
this, SLOT(updateButtonStates()) );
217 connect( widget, SIGNAL(titleChanged()),
this, SLOT(updateHeader()) );
218 connect( widget, SIGNAL(subTitleChanged()),
this, SLOT(updateHeader()) );
219 connect( widget, SIGNAL(explanationChanged()),
this, SLOT(updateHeader()) );
220 connect( widget, SIGNAL(autoAdvanceChanged()),
this, SLOT(updateButtonStates()) );
221 connect( widget, SIGNAL(windowTitleChanged(QString)),
this, SLOT(setWindowTitle(QString)) );
226 d->pageOrder = pageOrder;
227 d->hiddenPages.clear();
228 if ( pageOrder.empty() )
239 d->updateButtonStates();
245 d->hiddenPages.erase(
id );
247 d->hiddenPages.insert(
id );
260 return current ? current->
isComplete() :
false;
265 const int prev = d->previousPage();
280 std::vector<int>::const_iterator it = qBinaryFind( d->pageOrder.begin(), d->pageOrder.end(), d->currentId );
281 assert( it != d->pageOrder.end() );
286 while ( d->hiddenPages.find( *it ) != d->hiddenPages.end() );
288 if ( it == d->pageOrder.end() )
299 int Wizard::Private::previousPage()
const
301 if ( pageOrder.empty() )
304 std::vector<int>::const_iterator it = qBinaryFind( pageOrder.begin(), pageOrder.end(), currentId );
305 if ( it == pageOrder.begin() || it == pageOrder.end() )
310 }
while ( it != pageOrder.begin() && hiddenPages.find( *it ) != hiddenPages.end() );
317 const int prev = d->previousPage();
328 const std::map<int, WizardPage*>::const_iterator it = d->idToPage.find(
id );
335 return page( d->currentId );
341 return page( d->currentId );
346 Q_UNUSED( currentId )
352 Q_UNUSED( currentId )
360 const std::map<int, WizardPage*>::const_iterator it = d->idToPage.find(
id );
365 #include "moc_wizard.cpp"
const WizardPage * page(int id) const
void setPageOrder(const std::vector< int > &pages)
virtual void onNext(int currentId)
bool canGoToNextPage() const
void setCurrentPage(int id)
bool canGoToPreviousPage() const
bool isCommitPage() const
QString explanation() const
#define kleo_assert(cond)
virtual void onBack(int currentId)
const WizardPage * currentPageWidget() const
KGuiItem customNextButton() const
virtual bool isComplete() const =0
void setPage(int id, WizardPage *page)
void setPageVisible(int id, bool visible)