//============================================================================= // // File : OptionsDialog.cpp // Created on Fri 10 Feb 2006 18:52:18 by Szymon Stefanek // Based on dlg_options.cpp: Tue Jun 11 2000 02:39:12 by Szymon Stefanek // // This file is part of the KVIrc IRC Client distribution // Copyright (C) 2000-2010 Szymon Stefanek // // This program is FREE software. You can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your opinion) any later version. // // This program is distributed in the HOPE that it will be USEFUL, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, write to the Free Software Foundation, // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // //============================================================================= #include "OptionsDialog.h" #include "KviApplication.h" #include "KviOptions.h" #include "KviLocale.h" #include "KviIconManager.h" #include "KviMainWindow.h" #include "KviModule.h" #include "KviPointerHashTable.h" #include "KviTalVBox.h" #include "KviTalToolTip.h" #include "KviTalGroupBox.h" #include #include #include #include #include #include #include #include #include #include #include #include #include //FIXME: some headers must be hidden //extern KviModule * g_pOptionsModule; extern KviPointerHashTable * g_pOptionsDialogDict; extern KVIRC_API KviApplication * g_pApp; extern OptionsInstanceManager * g_pOptionsInstanceManager; OptionsDialogFrontWidget::OptionsDialogFrontWidget(QWidget *parent,const QString &szText) :KviOptionsWidget(parent) { setObjectName("general_options_front_widget"); createLayout(); QLabel * l = new QLabel(szText,this); l->setWordWrap(true); l->setAlignment(Qt::AlignTop); layout()->addWidget(l,0,0); } OptionsDialogFrontWidget::~OptionsDialogFrontWidget() { } OptionsDialogTreeWidgetItem::OptionsDialogTreeWidgetItem(QTreeWidget *parent,OptionsWidgetInstanceEntry * e) :QTreeWidgetItem() { m_pInstanceEntry = e; m_pOptionsWidget = 0; setText(0,e->szName); setIcon(0,*(g_pIconManager->getSmallIcon(e->eIcon))); parent->insertTopLevelItem(0, this); } OptionsDialogTreeWidgetItem::OptionsDialogTreeWidgetItem(QTreeWidgetItem *parent,OptionsWidgetInstanceEntry * e) :QTreeWidgetItem() { m_pInstanceEntry = e; m_pOptionsWidget = 0; setText(0,e->szName); setIcon(0,*(g_pIconManager->getSmallIcon(e->eIcon))); parent->insertChild(0, this); } OptionsDialogTreeWidgetItem::~OptionsDialogTreeWidgetItem() { } OptionsDialog::OptionsDialog(QWidget * par,const QString &szGroup,bool bModal) : QDialog(par) { setObjectName("general_options_dialog"); setWindowIcon(*(g_pIconManager->getSmallIcon(KviIconManager::KVIrc))); m_szGroup = szGroup; QString szDialogTitle; if(szGroup.isEmpty() || KviQString::equalCI(szGroup,"general")) { szDialogTitle = __tr2qs_ctx("General Preferences","options"); } else if(KviQString::equalCI(szGroup,"theme")) { szDialogTitle = __tr2qs_ctx("Theme Preferences","options"); } else { szDialogTitle = __tr2qs_ctx("KVIrc Preferences","options"); } QString szDialog = __tr2qs_ctx("This dialog contains a set of KVIrc settings.
Use the icons " \ "on the left to navigate through the option pages. The text box in the " \ "bottom left corner is a small search engine. It will highlight the " \ "pages that contain options related to the search term you have entered.","options"); QString szInfoTips; szInfoTips = __tr2qs_ctx("Many settings have tooltips that can be shown by holding " \ "the cursor over their label for a few seconds.","options"); QString szOkCancelButtons = __tr2qs_ctx("When you have finished, click \"OK\" to accept your changes " \ "or \"Cancel\" to discard them. Clicking \"Apply\" will commit your " \ "changes without closing the window.","options"); QString szFrontText = QString( "" \ "" \ "" \ "" \ "" \ "" \ "" \ "
" \ "

%1

" \ "
" \ "
" \ "
" \ "

" \ "%2" \ "

" \ "
" \ "

" \ "%3" \ "

" \ "
" \ "

" \ "%4" \ "

" \ "
" ).arg(szDialogTitle, szDialog, szInfoTips, szOkCancelButtons); QString szCaption = szDialogTitle + " - KVIrc"; setWindowTitle(szCaption); QGridLayout * g1 = new QGridLayout(this); QSplitter * spl = new QSplitter(Qt::Horizontal,this); spl->setChildrenCollapsible(false); g1->addWidget(spl,0,0,1,5); KviTalVBox * vbox = new KviTalVBox(spl); vbox->setSpacing(2); vbox->setMargin(3); // Controlling list view m_pTreeWidget = new QTreeWidget(vbox); m_pTreeWidget->header()->hide(); m_pTreeWidget->setRootIsDecorated(true); m_pTreeWidget->setSortingEnabled(false); m_pTreeWidget->setSizePolicy(QSizePolicy::MinimumExpanding,QSizePolicy::MinimumExpanding); connect(m_pTreeWidget,SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem *)),this,SLOT(treeWidgetItemSelectionChanged(QTreeWidgetItem *, QTreeWidgetItem *))); KviTalHBox * hbox = new KviTalHBox(vbox); hbox->setSpacing(2); hbox->setMargin(3); m_pSearchLineEdit = new QLineEdit(hbox); connect(m_pSearchLineEdit,SIGNAL(returnPressed()),this,SLOT(searchClicked())); m_pSearchButton = new QToolButton(hbox); m_pSearchButton->setIconSize(QSize(16,16)); m_pSearchButton->setIcon(*(g_pIconManager->getSmallIcon(KviIconManager::Search))); connect(m_pSearchButton,SIGNAL(clicked()),this,SLOT(searchClicked())); connect(m_pSearchLineEdit,SIGNAL(textChanged(const QString &)),this,SLOT(searchLineEditTextChanged(const QString &))); QString szTip = __tr2qs_ctx("

This is the search tool for this options dialog.

" \ "

You can enter a search term either in your native " \ "language or in english and press the button on the right. " \ "The pages that contain some options related to the " \ "search term will be highlighted and you will be able " \ "to quickly find them.

Try \"nickname\" for example.

","options"); KviTalToolTip::add(m_pSearchLineEdit,szTip); KviTalToolTip::add(m_pSearchButton,szTip); vbox = new KviTalVBox(spl); vbox->setSpacing(2); vbox->setMargin(3); m_pCategoryLabel = new QLabel(" ",vbox); m_pCategoryLabel->setObjectName("labgeneraloptions"); QFrame * f = new QFrame(vbox); f->setFrameStyle(QFrame::HLine | QFrame::Sunken); // Widget stack m_pWidgetStack = new QStackedWidget(vbox); vbox->setStretchFactor(m_pWidgetStack,1); // First widget visible m_pFrontWidget = new OptionsDialogFrontWidget(m_pWidgetStack,szFrontText); m_pWidgetStack->addWidget(m_pFrontWidget); int idx = m_pWidgetStack->indexOf(m_pFrontWidget); m_pWidgetStack->widget(idx)->raise(); // Ok,Cancel,Help QPushButton * b = new QPushButton(__tr2qs_ctx("&OK","options"),this); b->setObjectName("btnok"); KviTalToolTip::add(b,__tr2qs_ctx("Close this dialog, accepting all changes.","options")); connect(b,SIGNAL(clicked()),this,SLOT(okClicked())); //b->setMinimumWidth(whatIsThisWidth); b->setIcon(*(g_pIconManager->getSmallIcon(KviIconManager::Accept))); g1->addWidget(b,1,2); b = new QPushButton(__tr2qs_ctx("&Apply","options"),this); b->setObjectName("btnapply"); KviTalToolTip::add(b,__tr2qs_ctx("Commit all changes immediately.","options")); connect(b,SIGNAL(clicked()),this,SLOT(applyClicked())); b->setIcon(*(g_pIconManager->getSmallIcon(KviIconManager::Accept))); g1->addWidget(b,1,3); b = new QPushButton(__tr2qs_ctx("Cancel","options"),this); b->setObjectName("btncancel"); KviTalToolTip::add(b,__tr2qs_ctx("Close this dialog, discarding all changes.","options")); b->setDefault(true); //b->setMinimumWidth(whatIsThisWidth); connect(b,SIGNAL(clicked()),this,SLOT(cancelClicked())); b->setIcon(*(g_pIconManager->getSmallIcon(KviIconManager::Discard))); g1->addWidget(b,1,4); g1->setRowStretch(0,1); g1->setColumnStretch(1,1); fillTreeWidget(0,g_pOptionsInstanceManager->instanceEntryTree(),szGroup); if(!parent()) { if(KVI_OPTION_RECT(KviOption_rectGeneralOptionsDialogGeometry).y() < 5) KVI_OPTION_RECT(KviOption_rectGeneralOptionsDialogGeometry).setY(5); //setGeometry(KVI_OPTION_RECT(KviOption_rectGeneralOptionsDialogGeometry)); resize(KVI_OPTION_RECT(KviOption_rectGeneralOptionsDialogGeometry).width(), KVI_OPTION_RECT(KviOption_rectGeneralOptionsDialogGeometry).height()); move(KVI_OPTION_RECT(KviOption_rectGeneralOptionsDialogGeometry).x(), KVI_OPTION_RECT(KviOption_rectGeneralOptionsDialogGeometry).y()); } new QShortcut(Qt::Key_Escape,this,SLOT(close())); if(bModal) setWindowModality(par ? Qt::WindowModal : Qt::ApplicationModal); } OptionsDialog::~OptionsDialog() { if(!parent()) KVI_OPTION_RECT(KviOption_rectGeneralOptionsDialogGeometry) = QRect(pos().x(),pos().y(),size().width(),size().height()); if(g_pOptionsDialogDict) g_pOptionsDialogDict->remove(m_szGroup); } void OptionsDialog::showEvent(QShowEvent *e) { // setup a minimum size and move to the screen the main kvirc window is QRect r = g_pApp->desktop()->screenGeometry(g_pMainWindow); int w = r.width(); int h = r.height(); int ww = width(); int wh = height(); if(w < 800) { // 640x480 if(ww < 630)ww = 630; } else { if(ww < 770)ww = 770; } setGeometry(r.x() + ((w - ww) / 2),r.y() + ((h - wh) / 2),ww,wh); QWidget::showEvent(e); } void OptionsDialog::searchLineEditTextChanged(const QString &) { QString txt = m_pSearchLineEdit->text().trimmed(); m_pSearchButton->setEnabled(txt.length() > 0); } bool OptionsDialog::searchInSelectors(KviOptionsWidget *pOptionsWidget,const QStringList &lKeywords) { KviPointerList *selectors=pOptionsWidget->selectors(); bool bFoundSomethingHere=false; if(selectors->count()>0) { for(unsigned int i=0;icount();i++) { QString szText=selectors->at(i)->textForSearch(); QWidget* pWidget=selectors->at(i)->widgetToHighlight(); if (!pWidget) continue; QString szTmp=pWidget->toolTip(); szTmp=szTmp.replace(QRegExp("<[^<>]+>"),""); szText.append(szTmp); if(!szText.isEmpty()) { bool bOk = true; for(int j=0;jfont(); font.setBold(bOk); font.setUnderline(bOk); pWidget->setFont(font); } } } return bFoundSomethingHere; } bool OptionsDialog::recursiveSearch(OptionsDialogTreeWidgetItem * pItem,const QStringList &lKeywords) { if(!pItem)return false; if(!pItem->m_pOptionsWidget) { pItem->m_pOptionsWidget = g_pOptionsInstanceManager->getInstance(pItem->m_pInstanceEntry,m_pWidgetStack); m_pWidgetStack->addWidget(pItem->m_pOptionsWidget); } bool bFoundSomethingHere = false; KviOptionsWidget *pOptionsWidget=pItem->m_pOptionsWidget; QTabWidget *pTab= pOptionsWidget->tabWidget(); if (pTab) { for(int i=0;icount();i++) { QString szTxt = pTab->tabText(i); if(KviQString::equalCIN(szTxt,">>> ",4)) { szTxt.replace(">>> ",""); szTxt.replace(" <<<",""); } if (searchInSelectors((KviOptionsWidget*)pTab->widget(i),lKeywords)) { bFoundSomethingHere = true; szTxt.insert(0,">>> "); szTxt += QString(" <<<"); } pTab->setTabText(i,szTxt); } } else { if (searchInSelectors(pOptionsWidget,lKeywords)) bFoundSomethingHere = true; } QStringList szInstanceKeywords = pItem->m_pInstanceEntry->szKeywords.split(QChar(',')); // debug all the "search keywords" for each entry in the options tree // qDebug("OPT %s",pItem->m_pInstanceEntry->szKeywords.toUtf8().data()); for(int i=0;isetForeground(0, Qt::yellow); pItem->setBackground(0, Qt::red); } else { pItem->setForeground(0, Qt::black); pItem->setBackground(0, Qt::transparent); } bool bFoundSomethingInside = false; int ccount = pItem->childCount(); if(ccount > 0) { for(int j=0;jchild(j); bool bRet = recursiveSearch(pChild,lKeywords); if(bRet)bFoundSomethingInside = true; } } pItem->setSelected(false); pItem->setExpanded(bFoundSomethingInside); return (bFoundSomethingInside || bFoundSomethingHere); } void OptionsDialog::search(const QStringList &lKeywords) { m_pTreeWidget->setUpdatesEnabled(false); int count=m_pTreeWidget->topLevelItemCount(); for (int i=0;itopLevelItem(i); recursiveSearch(pChild,lKeywords); } m_pTreeWidget->setUpdatesEnabled(true); m_pTreeWidget->update(); } void OptionsDialog::search(const QString &szKeywords) { QStringList lKeywords = szKeywords.split(" ",QString::SkipEmptyParts); search(lKeywords); } void OptionsDialog::searchClicked() { QString szTxt = m_pSearchLineEdit->text().trimmed(); if(!szTxt.isEmpty()) search(szTxt); } void OptionsDialog::fillTreeWidget(QTreeWidgetItem * p,KviPointerList * l,const QString &szGroup,bool bNotContainedOnly) { if(!l)return; OptionsDialogTreeWidgetItem * it; OptionsWidgetInstanceEntry * e; KviPointerList tmp; tmp.setAutoDelete(false); for(e = l->first();e;e = l->next()) { // must be in the correct group // if we want only containers then well.. must be one e->bDoInsert = KviQString::equalCI(szGroup,e->szGroup) && ((!bNotContainedOnly) || e->bIsContainer || e->bIsNotContained); OptionsWidgetInstanceEntry * ee = tmp.first(); int idx = 0; while(ee) { if(ee->iPriority >= e->iPriority)break; idx++; ee = tmp.next(); } tmp.insert(idx,e); } for(e = tmp.first();e;e = tmp.next()) { if(e->bDoInsert) { if(p)it = new OptionsDialogTreeWidgetItem(p,e); else it = new OptionsDialogTreeWidgetItem(m_pTreeWidget,e); if(!it->m_pOptionsWidget) { it->m_pOptionsWidget = g_pOptionsInstanceManager->getInstance(it->m_pInstanceEntry,m_pWidgetStack); if(it->m_pOptionsWidget) m_pWidgetStack->addWidget(it->m_pOptionsWidget); } } else { it = (OptionsDialogTreeWidgetItem *)p; } if(e->pChildList) { if(e->bIsContainer) { // it's a container: add only eventual not contained children (containers or explicitly marked as not contained) fillTreeWidget(it,e->pChildList,szGroup,true); } else { // it's not a container, add any children fillTreeWidget(it,e->pChildList,szGroup,false); } } } } void OptionsDialog::treeWidgetItemSelectionChanged(QTreeWidgetItem* it, QTreeWidgetItem *) { if(it) { QString str = it->text(0); QTreeWidgetItem * par = it->parent(); while(par) { str.prepend(" :: "); str.prepend(par->text(0)); par = par->parent(); } str.prepend(""); str += ""; OptionsDialogTreeWidgetItem *i = (OptionsDialogTreeWidgetItem *)it; if(!i->m_pOptionsWidget) { i->m_pOptionsWidget = g_pOptionsInstanceManager->getInstance(i->m_pInstanceEntry,m_pWidgetStack); m_pWidgetStack->addWidget(i->m_pOptionsWidget); } //int idx = m_pWidgetStack->indexOf(i->m_pOptionsWidget); m_pWidgetStack->setCurrentWidget(i->m_pOptionsWidget); m_pCategoryLabel->setText(str); } } /* OptionsDialogTreeWidgetItem * OptionsDialog::findItemByPage(OptionsDialogTreeWidgetItem *it,KviOptionsWidget * pPage) { if(!it)return 0; if(it->m_pOptionsWidget == pPage)return it; OptionsDialogTreeWidgetItem *i; int ccount = it->childCount(); for(int j=0;jchild(j); i = findItemByPage(i,pPage); if(i)return i; } // not found in the children tree.. look in the next sibling for(int j=0;jchild(j); i = findItemByPage(i,pPage); if(i)return i; } i = (OptionsDialogTreeWidgetItem *)(it->nextSibling()); if(i) { i = findItemByPage(i,pPage); if(i)return i; } return 0; } */ void OptionsDialog::pageWantsToSwitchToAdvancedPage(KviOptionsWidget *) { // unused } void OptionsDialog::applyClicked() { apply(false); } void OptionsDialog::apply(bool bDialogAboutToClose) { int count=m_pTreeWidget->topLevelItemCount(); int curTab=-1; OptionsDialogTreeWidgetItem * it; if(!bDialogAboutToClose) { // bring up the current widget again! it = (OptionsDialogTreeWidgetItem *)m_pTreeWidget->currentItem(); //checking if the check of the check is checkable if(it) if(it->m_pOptionsWidget) if(it->m_pOptionsWidget->tabWidget()) curTab = it->m_pOptionsWidget->tabWidget()->currentIndex(); } for (int i=0;itopLevelItem(i); recursiveCommit(it); } if(!bDialogAboutToClose) { // bring up the current widget again! it = (OptionsDialogTreeWidgetItem *)m_pTreeWidget->currentItem(); if(it) { treeWidgetItemSelectionChanged(it, 0); if(curTab > 0 && it->m_pOptionsWidget) if(it->m_pOptionsWidget->tabWidget()) it->m_pOptionsWidget->tabWidget()->setCurrentIndex(curTab); } } g_pApp->saveConfiguration(); } void OptionsDialog::okClicked() { apply(true); deleteLater(); } void OptionsDialog::cancelClicked() { deleteLater(); } void OptionsDialog::closeEvent(QCloseEvent *e) { e->ignore(); deleteLater(); } void OptionsDialog::recursiveCommit(OptionsDialogTreeWidgetItem *it) { // First commit the children if(!it) return; int count=it->childCount(); for (int i=0;ichild(i); recursiveCommit(pChild); } // then the parents if(it->m_pOptionsWidget) { it->m_pOptionsWidget->commit(); delete it->m_pOptionsWidget; it->m_pOptionsWidget = 0; } //refreshTreeWidget(); // <-- this tends to jump into infinite recursion } void OptionsDialog::keyPressEvent( QKeyEvent * e ) { if(e->key()==Qt::Key_Return) e->accept(); else e->ignore(); }