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