00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
#include <qcheckbox.h>
00027
#include <qfile.h>
00028
#include <qhbox.h>
00029
#include <qlabel.h>
00030
#include <qlayout.h>
00031
#include <qpushbutton.h>
00032
#include <qregexp.h>
00033
#include <qtextstream.h>
00034
#include <qimage.h>
00035
00036
#include <kaboutdata.h>
00037
#include <kapplication.h>
00038
#include <kconfig.h>
00039
#include <kdebug.h>
00040
#include <kglobal.h>
00041
#include <kiconloader.h>
00042
#include <klocale.h>
00043
#include <kpushbutton.h>
00044
#include <kseparator.h>
00045
#include <kstandarddirs.h>
00046
#include <kstdguiitem.h>
00047
#include <ktextbrowser.h>
00048
#include <kiconeffect.h>
00049
#include <kglobalsettings.h>
00050
#include <kwin.h>
00051
00052
#include "ktip.h"
00053
00054
00055 KTipDatabase::KTipDatabase(
const QString &_tipFile)
00056 {
00057
QString tipFile = _tipFile;
00058
if (tipFile.
isEmpty())
00059 tipFile = QString::fromLatin1(KGlobal::instance()->aboutData()->appName()) +
"/tips";
00060
00061 loadTips(tipFile);
00062
00063
if (!mTips.isEmpty())
00064 mCurrent = kapp->random() % mTips.count();
00065 }
00066
00067
00068 KTipDatabase::KTipDatabase(
const QStringList& tipsFiles )
00069 {
00070
if ( tipsFiles.isEmpty() || ( ( tipsFiles.count() == 1 ) && tipsFiles.first().isEmpty() ) )
00071 {
00072 addTips(QString::fromLatin1(KGlobal::instance()->aboutData()->appName()) +
"/tips");
00073 }
00074
else
00075 {
00076
for (QStringList::ConstIterator it = tipsFiles.begin(); it != tipsFiles.end(); ++it)
00077 addTips( *it );
00078 }
00079
if (!mTips.isEmpty())
00080 mCurrent = kapp->random() % mTips.count();
00081
00082 }
00083
00084
void KTipDatabase::loadTips(
const QString &tipFile)
00085 {
00086 mTips.clear();
00087 addTips(tipFile);
00088 }
00089
00090
00091
00092
00093
void KTipDatabase::addTips(
const QString& tipFile )
00094 {
00095
QString fileName =
locate(
"data", tipFile);
00096
00097
if (fileName.
isEmpty())
00098 {
00099
kdDebug() <<
"KTipDatabase::addTips: can't find '" << tipFile <<
"' in standard dirs" <<
endl;
00100
return;
00101 }
00102
00103
QFile file(fileName);
00104
if (!file.
open(IO_ReadOnly))
00105 {
00106
kdDebug() <<
"KTipDatabase::addTips: can't open '" << fileName <<
"' for reading" <<
endl;
00107
return;
00108 }
00109
00110
QByteArray data = file.
readAll();
00111
QString content =
QString::fromUtf8(data.data(), data.size());
00112
const QRegExp rx(
"\\n+");
00113
00114
int pos = -1;
00115
while ((pos = content.
find(
"<html>", pos + 1,
false)) != -1)
00116 {
00117
00118
00119
QString tip = content
00120 .
mid(pos + 6, content.
find(
"</html>", pos,
false) - pos - 6)
00121 .replace(rx,
"\n");
00122
if (!tip.
endsWith(
"\n"))
00123 tip +=
"\n";
00124
if (tip.
startsWith(
"\n"))
00125 tip = tip.
mid(1);
00126
if (tip.
isEmpty())
00127 {
00128
kdDebug() <<
"Empty tip found! Skipping! " << pos <<
endl;
00129
continue;
00130 }
00131 mTips.append(tip);
00132 }
00133
00134 file.
close();
00135
00136 }
00137
00138 void KTipDatabase::nextTip()
00139 {
00140
if (mTips.isEmpty())
00141
return ;
00142 mCurrent += 1;
00143
if (mCurrent >= (
int) mTips.count())
00144 mCurrent = 0;
00145 }
00146
00147
00148 void KTipDatabase::prevTip()
00149 {
00150
if (mTips.isEmpty())
00151
return ;
00152 mCurrent -= 1;
00153
if (mCurrent < 0)
00154 mCurrent = mTips.count() - 1;
00155 }
00156
00157
00158 QString KTipDatabase::tip()
const
00159
{
00160
if (mTips.isEmpty())
00161
return QString::null;
00162
return mTips[mCurrent];
00163 }
00164
00165
KTipDialog *KTipDialog::mInstance = 0;
00166
00167
00168 KTipDialog::KTipDialog(
KTipDatabase *db,
QWidget *parent,
const char *name)
00169 :
KDialog(parent, name)
00170 {
00175
bool isTipDialog = (parent);
00176
00177
QImage img;
00178
int h,s,v;
00179
00180 mBlendedColor =
KGlobalSettings::activeTitleColor();
00181 mBlendedColor.hsv(&h,&s,&v);
00182 mBlendedColor.
setHsv(h,
int(s*(71/76.0)),
int(v*(67/93.0)));
00183
00184
if (!isTipDialog)
00185 {
00186 img =
QImage(
locate(
"data",
"kdewizard/pics/wizard_small.png"));
00187
00188 KIconEffect::colorize(img, mBlendedColor, 1.0);
00189 QRgb colPixel( img.
pixel(0,0) );
00190
00191 mBlendedColor =
QColor(qRed(colPixel),qGreen(colPixel),qBlue(colPixel));
00192 }
00193
00194 mBaseColor =
KGlobalSettings::alternateBackgroundColor();
00195 mBaseColor.hsv(&h,&s,&v);
00196 mBaseColor.
setHsv(h,
int(s*(10/6.0)),
int(v*(93/99.0)));
00197
00198 mTextColor =
KGlobalSettings::textColor();
00199
00200
00201 mDatabase = db;
00202
00203 setCaption(i18n(
"Tip of the Day"));
00204 KWin::setIcons( winId(),
00205 KGlobal::iconLoader()->loadIcon(
"idea", KIcon::NoGroup, 32 ),
00206 KGlobal::iconLoader()->loadIcon(
"idea", KIcon::NoGroup, 16 ) );
00207
00208
QVBoxLayout *vbox =
new QVBoxLayout(
this,
marginHint(),
spacingHint());
00209
00210
if (isTipDialog)
00211 {
00212
QHBoxLayout *pl =
new QHBoxLayout(vbox, 0, 0);
00213
00214
QLabel *bulb =
new QLabel(
this);
00215 bulb->
setPixmap(
locate(
"data",
"kdeui/pics/ktip-bulb.png"));
00216 pl->addWidget(bulb);
00217
00218 QLabel *titlePane =
new QLabel(
this);
00219 titlePane->setBackgroundPixmap(
locate(
"data",
"kdeui/pics/ktip-background.png"));
00220 titlePane->
setText(i18n(
"Did you know...?\n"));
00221 titlePane->
setFont(
QFont(KGlobalSettings::generalFont().family(), 20, QFont::Bold));
00222 titlePane->
setAlignment(QLabel::AlignCenter);
00223 pl->addWidget(titlePane, 100);
00224 }
00225
00226
QHBox *hbox =
new QHBox(
this);
00227 hbox->
setSpacing(0);
00228 hbox->setFrameStyle(QFrame::Panel | QFrame::Sunken);
00229 vbox->addWidget(hbox);
00230
00231 QHBox *tl =
new QHBox(hbox);
00232 tl->setMargin(7);
00233 tl->setBackgroundColor(mBlendedColor);
00234
00235 QHBox *topLeft =
new QHBox(tl);
00236 topLeft->setMargin(15);
00237 topLeft->setBackgroundColor(mBaseColor);
00238
00239 mTipText =
new KTextBrowser(topLeft);
00240
00241 mTipText->setWrapPolicy( QTextEdit::AtWordOrDocumentBoundary );
00242 mTipText->mimeSourceFactory()->addFilePath(
00243 KGlobal::dirs()->findResourceDir(
"data",
"kdewizard/pics")+
"kdewizard/pics/");
00244 mTipText->setFrameStyle(QFrame::NoFrame | QFrame::Plain);
00245 mTipText->setHScrollBarMode(QScrollView::AlwaysOff);
00246 mTipText->setLinkUnderline(
false);
00247
00248
QStyleSheet *sheet = mTipText->styleSheet();
00249
QStyleSheetItem *item = sheet->
item(
"a");
00250 item->
setFontWeight(QFont::Bold);
00251 mTipText->setStyleSheet(sheet);
00252
QPalette pal = mTipText->palette();
00253 pal.
setColor( QPalette::Active, QColorGroup::Link, mBlendedColor );
00254 pal.
setColor( QPalette::Inactive, QColorGroup::Link, mBlendedColor );
00255 mTipText->setPalette(pal);
00256
00257
QStringList icons =
KGlobal::dirs()->
resourceDirs(
"icon");
00258 QStringList::Iterator it;
00259
for (it = icons.begin(); it != icons.end(); ++it)
00260 mTipText->mimeSourceFactory()->addFilePath(*it);
00261
00262
if (!isTipDialog)
00263 {
00264
QLabel *l =
new QLabel(hbox);
00265 l->
setPixmap(img);
00266 l->setBackgroundColor(mBlendedColor);
00267 l->
setAlignment(Qt::AlignRight | Qt::AlignBottom);
00268
00269 resize(550, 230);
00270
QSize sh = size();
00271
00272
QRect rect =
KGlobalSettings::splashScreenDesktopGeometry();
00273
00274 move(rect.
x() + (rect.
width() - sh.
width())/2,
00275 rect.
y() + (rect.
height() - sh.
height())/2);
00276 }
00277
00278
KSeparator* sep =
new KSeparator( KSeparator::HLine,
this);
00279 vbox->addWidget(sep);
00280
00281
QHBoxLayout *hbox2 =
new QHBoxLayout(vbox, 4);
00282
00283 mTipOnStart =
new QCheckBox(i18n(
"&Show tips on startup"),
this);
00284 hbox2->addWidget(mTipOnStart, 1);
00285
00286
KPushButton *prev =
new KPushButton( KStdGuiItem::back(
00287 KStdGuiItem::UseRTL ),
this );
00288 prev->
setText( i18n(
"&Previous") );
00289 hbox2->addWidget(prev);
00290
00291 KPushButton *next =
new KPushButton( KStdGuiItem::forward(
00292 KStdGuiItem::UseRTL ),
this );
00293 next->setText( i18n(
"Opposite to Previous",
"&Next") );
00294 hbox2->addWidget(next);
00295
00296 KPushButton *ok =
new KPushButton(KStdGuiItem::close(),
this);
00297 ok->
setDefault(
true);
00298 hbox2->addWidget(ok);
00299
00300
KConfigGroup config(kapp->config(),
"TipOfDay");
00301 mTipOnStart->
setChecked(config.
readBoolEntry(
"RunOnStart",
false));
00302
00303 connect(next, SIGNAL(clicked()),
this, SLOT(nextTip()));
00304 connect(prev, SIGNAL(clicked()),
this, SLOT(prevTip()));
00305 connect(ok, SIGNAL(clicked()),
this, SLOT(
accept()));
00306 connect(mTipOnStart, SIGNAL(toggled(
bool)),
this, SLOT(showOnStart(
bool)));
00307
00308 ok->setFocus();
00309
00310 nextTip();
00311 }
00312
00313 KTipDialog::~KTipDialog()
00314 {
00315
if( mInstance==
this )
00316 mInstance = 0L;
00317 }
00318
00319 void KTipDialog::showTip(
const QString &tipFile,
bool force)
00320 {
00321
showTip(kapp->mainWidget(), tipFile, force);
00322 }
00323
00324 void KTipDialog::showTip(
QWidget *parent,
const QString &tipFile,
bool force)
00325 {
00326
showMultiTip( parent,
QStringList(tipFile), force );
00327 }
00328
00329 void KTipDialog::showMultiTip(
QWidget *parent,
const QStringList &tipFiles,
bool force)
00330 {
00331
KConfigGroup configGroup(kapp->config(),
"TipOfDay");
00332
00333
const bool runOnStart = configGroup.
readBoolEntry(
"RunOnStart",
false);
00334
00335
if (!force)
00336 {
00337
if (!runOnStart)
00338
return;
00339
00340
bool hasLastShown = configGroup.
hasKey(
"TipLastShown");
00341
if (hasLastShown)
00342 {
00343
const int oneDay = 24*60*60;
00344
QDateTime lastShown = configGroup.
readDateTimeEntry(
"TipLastShown");
00345
00346
if (lastShown.
secsTo(QDateTime::currentDateTime()) < (oneDay + (kapp->random() % (10*oneDay))))
00347
return;
00348 }
00349 configGroup.
writeEntry(
"TipLastShown", QDateTime::currentDateTime());
00350 kapp->config()->sync();
00351
if (!hasLastShown)
00352
return;
00353 }
00354
00355
if (!mInstance)
00356 mInstance =
new KTipDialog(
new KTipDatabase(tipFiles), parent);
00357
else
00358
00359
00360 mInstance->
mTipOnStart->
setChecked(runOnStart);
00361
00362 mInstance->
show();
00363 mInstance->raise();
00364 }
00365
00366
void KTipDialog::prevTip()
00367 {
00368 mDatabase->
prevTip();
00369 mTipText->setText(QString::fromLatin1(
00370
"<qt text=\"%1\" bgcolor=\"%2\">%3</qt>")
00371 .arg(mTextColor.
name())
00372 .arg(mBaseColor.
name())
00373 .arg(i18n(mDatabase->
tip().
utf8())));
00374 }
00375
00376
void KTipDialog::nextTip()
00377 {
00378 mDatabase->
nextTip();
00379 mTipText->setText(QString::fromLatin1(
"<qt text=\"%1\" bgcolor=\"%2\">%3</qt>")
00380 .arg(mTextColor.
name())
00381 .arg(mBaseColor.
name())
00382 .arg(i18n(mDatabase->
tip().
utf8())));
00383 }
00384
00385
void KTipDialog::showOnStart(
bool on)
00386 {
00387
setShowOnStart(on);
00388 }
00389
00390 void KTipDialog::setShowOnStart(
bool on)
00391 {
00392
KConfigGroup config(kapp->config(),
"TipOfDay");
00393 config.
writeEntry(
"RunOnStart", on);
00394 config.
sync();
00395 }
00396
00397
bool KTipDialog::eventFilter(
QObject *o,
QEvent *e)
00398 {
00399
if (o == mTipText && e->
type()== QEvent::KeyPress &&
00400 (((
QKeyEvent *)e)->key() == Key_Return ||
00401 ((
QKeyEvent *)e)->key() == Key_Space ))
00402
accept();
00403
00404
00405
00406
00407
00408
00409
00410
return QWidget::eventFilter( o, e );
00411 }
00412
00413
void KTipDialog::virtual_hook(
int id,
void* data )
00414 {
00415 KDialog::virtual_hook(
id, data );
00416 }
00417
00418
#include "ktip.moc"