• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kdeui

ktip.cpp

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

kdeui

Skip menu "kdeui"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal