kdeui Library API Documentation

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", 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 // 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"
KDE Logo
This file is part of the documentation for kdeui Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Apr 14 00:10:17 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003