# kdeui Library API Documentation

Overview | Class Hierarchy | Classes | Classes (annotated) | Members | Namespaces | Source Files

# ktip.cpp

    00001 /*****************************************************************
    00002
    00003 Copyright (c) 2000-2003 Matthias Hoelzer-Kluepfel <mhk@kde.org>
    00004                         Tobias Koenig <tokoe@kde.org>
    00005                         Daniel Molkentin <molkentin@kde.org>
    00006
    00007 Permission is hereby granted, free of charge, to any person obtaining a copy
    00008 of this software and associated documentation files (the "Software"), to deal
    00009 in the Software without restriction, including without limitation the rights
    00010 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    00011 copies of the Software, and to permit persons to whom the Software is
    00012 furnished to do so, subject to the following conditions:
    00013
    00014 The above copyright notice and this permission notice shall be included in
    00015 all copies or substantial portions of the Software.
    00016
    00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    00019 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    00020 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
    00021 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
    00022 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    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 // if you change something here, please update the script
    00091 // preparetips, which depends on extracting exactly the same
    00092 // text as done here.
    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        // to make translations work, tip extraction here must exactly
    00118        // match what is done by the preparetips script
    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     // colorize and check to figure the correct color
    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", true));
    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", true);
    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            // Show tip roughly once a week
    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; // Don't show tip on first start
    00353     }
    00354
    00355     if (!mInstance)
    00356     mInstance = new KTipDialog(new KTipDatabase(tipFiles), parent);
    00357     else
    00358     // The application might have changed the RunOnStart option in its own
    00359     // configuration dialog, so we should update the checkbox.
    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     // If the user presses Return or Space, we close the dialog as if the
    00405     // default button was pressed even if the KTextBrowser has the keyboard
    00406     // focus. This could have the bad side-effect that the user cannot use the
    00407     // keyboard to open urls in the KTextBrowser, so we just let it handle
    00408     // the key event _additionally_. (Antonio)
    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"

This file is part of the documentation for kdeui Library Version 3.4.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jun 11 20:20:24 2005 by doxygen 1.4.1 written by Dimitri van Heesch, © 1997-2003