|
|
|
/**
|
|
|
|
* This file is part of the System Settings package
|
|
|
|
* Copyright (C) 2005 Benjamin C Meyer (ben+systempreferences at meyerhome dot net)
|
|
|
|
*
|
|
|
|
* 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 option) any later version.
|
|
|
|
*
|
|
|
|
* This library 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
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public License
|
|
|
|
* along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
* the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "mainwindow.h"
|
|
|
|
|
|
|
|
#include <kstdaction.h>
|
|
|
|
#include <tqwhatsthis.h>
|
|
|
|
#include <tqlabel.h>
|
|
|
|
#include <tqvbox.h>
|
|
|
|
#include <kaction.h>
|
|
|
|
#include <tqtoolbutton.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
#include <kservicegroup.h>
|
|
|
|
#include <tqlayout.h>
|
|
|
|
#include <tqwidgetstack.h>
|
|
|
|
#include <tqtimer.h>
|
|
|
|
#include <kiconloader.h>
|
|
|
|
#include <kcmoduleloader.h>
|
|
|
|
#include <kdialogbase.h>
|
|
|
|
#include <kiconviewsearchline.h>
|
|
|
|
#include <kapplication.h>
|
|
|
|
#include <kaboutapplication.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <kcmoduleproxy.h>
|
|
|
|
#include <kbugreport.h>
|
|
|
|
#include <kmenubar.h>
|
|
|
|
#include <kactionclasses.h>
|
|
|
|
#include <ktoolbarbutton.h>
|
|
|
|
#include <tqtabbar.h>
|
|
|
|
|
|
|
|
#include "kcmsearch.h"
|
|
|
|
#include "modulesview.h"
|
|
|
|
#include "moduleiconitem.h"
|
|
|
|
#include "kcmodulemenu.h"
|
|
|
|
#include "kcmultiwidget.h"
|
|
|
|
|
|
|
|
MainWindow::MainWindow(bool embed, const TQString & menuFile,
|
|
|
|
TQWidget *tqparent, const char *name) :
|
|
|
|
KMainWindow(tqparent,name), menu(NULL), embeddedWindows(embed),
|
|
|
|
groupWidget(NULL), selectedPage(0), dummyAbout(NULL) {
|
|
|
|
|
|
|
|
// Load the menu structure in from disk.
|
|
|
|
menu = new KCModuleMenu( menuFile );
|
|
|
|
|
|
|
|
moduleTabs = new KTabWidget(this, "moduletabs",
|
|
|
|
TQTabWidget::Top|TQTabWidget::Rounded);
|
|
|
|
buildMainWidget();
|
|
|
|
buildActions();
|
|
|
|
setupGUI(ToolBar|Save|Create,TQString());
|
|
|
|
widgetChange();
|
|
|
|
}
|
|
|
|
|
|
|
|
MainWindow::~MainWindow()
|
|
|
|
{
|
|
|
|
delete moduleTabs;
|
|
|
|
delete windowStack;
|
|
|
|
delete menu;
|
|
|
|
delete dummyAbout;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::buildMainWidget()
|
|
|
|
{
|
|
|
|
windowStack = new TQWidgetStack( this, "widgetstack" );
|
|
|
|
|
|
|
|
// Top level pages.
|
|
|
|
TQValueList<MenuItem> subMenus = menu->menuList();
|
|
|
|
TQValueList<MenuItem>::iterator it;
|
|
|
|
KCScrollView *modulesScroller;
|
|
|
|
moduleTabs->show();
|
|
|
|
for ( it = subMenus.begin(); it != subMenus.end(); ++it ) {
|
|
|
|
if( (*it).menu ) {
|
|
|
|
modulesScroller = new KCScrollView(moduleTabs);
|
|
|
|
ModulesView *modulesView = new ModulesView( menu, (*it).subMenu, modulesScroller->viewport(), "modulesView" );
|
|
|
|
modulesViewList.append(modulesView);
|
|
|
|
connect(modulesView, TQT_SIGNAL(itemSelected(TQIconViewItem* )), TQT_TQOBJECT(this), TQT_SLOT(slotItemSelected(TQIconViewItem*)));
|
|
|
|
modulesScroller->addChild(modulesView);
|
|
|
|
moduleTabs->addTab(modulesScroller, (*it).caption);
|
|
|
|
overviewPages.append(modulesScroller);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
windowStack->addWidget(moduleTabs);
|
|
|
|
windowStack->raiseWidget(moduleTabs);
|
|
|
|
setCentralWidget(windowStack);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::buildActions()
|
|
|
|
{
|
|
|
|
KStdAction::quit(TQT_TQOBJECT(this), TQT_SLOT( close() ), actionCollection());
|
|
|
|
|
|
|
|
resetModule = new KAction(i18n("Undo Changes"), 0, TQT_TQOBJECT(this),
|
|
|
|
TQT_SLOT(showAllModules()), actionCollection(), "resetModule" );
|
|
|
|
resetModule->setEnabled(false);
|
|
|
|
|
|
|
|
defaultModule = new KAction(i18n("Reset to Defaults"), 0, TQT_TQOBJECT(this),
|
|
|
|
TQT_SLOT(showAllModules()), actionCollection(), "defaultModule" );
|
|
|
|
defaultModule->setEnabled(false);
|
|
|
|
|
|
|
|
if( embeddedWindows ) {
|
|
|
|
showAllAction = new KAction(i18n("Overview"), TQApplication::reverseLayout() ? "forward" : "back", 0, TQT_TQOBJECT(this),
|
|
|
|
TQT_SLOT(showAllModules()), actionCollection(), "showAll" );
|
|
|
|
showAllAction->setEnabled(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
aboutModuleAction = new KAction(i18n("About Current Module"), 0, TQT_TQOBJECT(this), TQT_SLOT(aboutCurrentModule()), actionCollection(), "help_about_module");
|
|
|
|
resetModuleHelp();
|
|
|
|
|
|
|
|
// Search
|
|
|
|
TQHBox *hbox = new TQHBox(0);
|
|
|
|
hbox->setMaximumWidth( 400 );
|
|
|
|
|
|
|
|
KcmSearch* search = new KcmSearch(&modulesViewList, hbox, "search");
|
|
|
|
hbox->setStretchFactor(search,1);
|
|
|
|
connect(search, TQT_SIGNAL(searchHits(const TQString &, int *, int)), TQT_TQOBJECT(this), TQT_SLOT(slotSearchHits(const TQString &, int *, int)));
|
|
|
|
|
|
|
|
TQVBox *vbox = new TQVBox(hbox);
|
|
|
|
generalHitLabel = new TQLabel(vbox);
|
|
|
|
vbox->setStretchFactor(generalHitLabel,1);
|
|
|
|
advancedHitLabel = new TQLabel(vbox);
|
|
|
|
vbox->setStretchFactor(advancedHitLabel,1);
|
|
|
|
|
|
|
|
hbox->setStretchFactor(vbox,1);
|
|
|
|
|
|
|
|
// "Search:" label
|
|
|
|
TQLabel *searchLabel = new TQLabel( this, "SearchLabel");
|
|
|
|
searchLabel->setText( i18n("&Search:") );
|
|
|
|
searchLabel->setFont(KGlobalSettings::toolBarFont());
|
|
|
|
searchLabel->setMargin(2);
|
|
|
|
searchText = new KWidgetAction( searchLabel, i18n("&Search:"), Key_F6, 0, 0, actionCollection(), "searchText" );
|
|
|
|
searchLabel->setBuddy( search );
|
|
|
|
|
|
|
|
// The search box.
|
|
|
|
searchAction = new KWidgetAction( hbox, i18n( "Search System Settings" ), 0,
|
|
|
|
0, 0, actionCollection(), "search" );
|
|
|
|
searchAction->setShortcutConfigurable( false );
|
|
|
|
searchAction->setAutoSized( true );
|
|
|
|
TQWhatsThis::add( search, i18n( "Search Bar<p>Enter a search term." ) );
|
|
|
|
|
|
|
|
// The Clear search box button.
|
|
|
|
KToolBarButton *clearWidget = new KToolBarButton(TQApplication::reverseLayout() ? "clear_left" : "locationbar_erase",
|
|
|
|
0, this);
|
|
|
|
searchClear = new KWidgetAction( clearWidget, TQString(""), CTRL+Key_L, TQT_TQOBJECT(search), TQT_SLOT(clear()),
|
|
|
|
actionCollection(), "searchReset");
|
|
|
|
connect(clearWidget, TQT_SIGNAL(clicked()), searchClear, TQT_SLOT(activate()));
|
|
|
|
searchClear->setWhatsThis( i18n( "Reset Search\n"
|
|
|
|
"Resets the search so that "
|
|
|
|
"all items are shown again." ) );
|
|
|
|
|
|
|
|
// Top level pages.
|
|
|
|
TQValueList<MenuItem> subMenus = menu->menuList();
|
|
|
|
TQValueList<MenuItem>::iterator it;
|
|
|
|
for ( it = subMenus.begin(); it != subMenus.end(); ++it ) {
|
|
|
|
if( (*it).menu ) {
|
|
|
|
KServiceGroup::Ptr group = KServiceGroup::group( (*it).subMenu );
|
|
|
|
if ( !group ){
|
|
|
|
kdDebug() << "Invalid Group \"" << (*it).subMenu << "\". Check your installation."<< endl;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
KRadioAction *newAction = new KRadioAction( group->caption(), group->icon(), KShortcut(), TQT_TQOBJECT(this),
|
|
|
|
TQT_SLOT(slotTopPage()), actionCollection(), group->relPath() );
|
|
|
|
pageActions.append(newAction);
|
|
|
|
kdDebug() << "relpath is :" << group->relPath() << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pageActions.at(0)->setChecked(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::aboutCurrentModule()
|
|
|
|
{
|
|
|
|
if(!groupWidget)
|
|
|
|
return;
|
|
|
|
|
|
|
|
KCModuleProxy* module = groupWidget->currentModule();
|
|
|
|
if( module && module->aboutData() ){
|
|
|
|
KAboutApplication dlg( module->aboutData() );
|
|
|
|
dlg.exec();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::groupModulesFinished()
|
|
|
|
{
|
|
|
|
showAllModules();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::showAllModules()
|
|
|
|
{
|
|
|
|
windowStack->raiseWidget(moduleTabs);
|
|
|
|
|
|
|
|
// Reset the widget for normal all widget viewing
|
|
|
|
groupWidget = 0;
|
|
|
|
widgetChange();
|
|
|
|
|
|
|
|
if( embeddedWindows ) {
|
|
|
|
showAllAction->setEnabled(false);
|
|
|
|
}
|
|
|
|
aboutModuleAction->setEnabled(false);
|
|
|
|
|
|
|
|
searchText->setEnabled(true);
|
|
|
|
searchClear->setEnabled(true);
|
|
|
|
searchAction->setEnabled(true);
|
|
|
|
|
|
|
|
KRadioAction *currentRadioAction;
|
|
|
|
for ( currentRadioAction = pageActions.first(); currentRadioAction; currentRadioAction = pageActions.next()) {
|
|
|
|
currentRadioAction->setEnabled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
resetModuleHelp();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotItemSelected( TQIconViewItem *item ){
|
|
|
|
ModuleIconItem *mItem = (ModuleIconItem *)item;
|
|
|
|
|
|
|
|
if( !mItem )
|
|
|
|
return;
|
|
|
|
|
|
|
|
groupWidget = moduleItemToWidgetDict.find(mItem);
|
|
|
|
scrollView = moduleItemToScrollerDict.find(mItem);
|
|
|
|
|
|
|
|
if(groupWidget==0) {
|
|
|
|
TQValueList<KCModuleInfo> list = mItem->modules;
|
|
|
|
KDialogBase::DialogType type = KDialogBase::IconList;
|
|
|
|
if(list.count() == 1) {
|
|
|
|
type=KDialogBase::Plain;
|
|
|
|
}
|
|
|
|
|
|
|
|
scrollView = new KCScrollView(windowStack);
|
|
|
|
groupWidget = new KCMultiWidget(type, scrollView->viewport(), "moduleswidget");
|
|
|
|
scrollView->addChild(groupWidget);
|
|
|
|
windowStack->addWidget(scrollView);
|
|
|
|
moduleItemToScrollerDict.insert(mItem,scrollView);
|
|
|
|
moduleItemToWidgetDict.insert(mItem,groupWidget);
|
|
|
|
|
|
|
|
connect(groupWidget, TQT_SIGNAL(aboutToShow( KCModuleProxy * )), TQT_TQOBJECT(this), TQT_SLOT(updateModuleHelp( KCModuleProxy * )));
|
|
|
|
connect(groupWidget, TQT_SIGNAL(aboutToShowPage( TQWidget* )), TQT_TQOBJECT(this), TQT_SLOT(widgetChange()));
|
|
|
|
connect(groupWidget, TQT_SIGNAL(finished()), TQT_TQOBJECT(this), TQT_SLOT(groupModulesFinished()));
|
|
|
|
connect(groupWidget, TQT_SIGNAL(close()), TQT_TQOBJECT(this), TQT_SLOT(showAllModules()));
|
|
|
|
|
|
|
|
TQValueList<KCModuleInfo>::iterator it;
|
|
|
|
for ( it = list.begin(); it != list.end(); ++it ){
|
|
|
|
qDebug("adding %s %s", (*it).moduleName().latin1(), (*it).fileName().latin1());
|
|
|
|
groupWidget->addModule( *it );
|
|
|
|
}
|
|
|
|
groupWidget->reparent(scrollView->viewport(), 0, TQPoint());
|
|
|
|
scrollView->reparent(windowStack, 0, TQPoint());
|
|
|
|
}
|
|
|
|
|
|
|
|
if( embeddedWindows ) {
|
|
|
|
windowStack->raiseWidget( scrollView );
|
|
|
|
|
|
|
|
setCaption( mItem->text() );
|
|
|
|
showAllAction->setEnabled(true);
|
|
|
|
searchText->setEnabled(false);
|
|
|
|
searchClear->setEnabled(false);
|
|
|
|
searchAction->setEnabled(false);
|
|
|
|
|
|
|
|
KRadioAction *currentRadioAction;
|
|
|
|
for ( currentRadioAction = pageActions.first(); currentRadioAction; currentRadioAction = pageActions.next()) {
|
|
|
|
currentRadioAction->setEnabled(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
scrollView->show();
|
|
|
|
}
|
|
|
|
groupWidget->show();
|
|
|
|
|
|
|
|
// We resize and expand the window if neccessary, but only once the window has been updated.
|
|
|
|
// Some modules seem to dynamically change thier size. The new size is only available
|
|
|
|
// once the dialog is updated. :-/ -SBE
|
|
|
|
TQTimer::singleShot(0,this,TQT_SLOT(timerResize()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::timerResize() {
|
|
|
|
TQSize currentSize = size();
|
|
|
|
TQSize newSize = currentSize.expandedTo(tqsizeHint());
|
|
|
|
// Avoid resizing if possible.
|
|
|
|
if(newSize!=currentSize) {
|
|
|
|
resize(newSize);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::updateModuleHelp( KCModuleProxy *currentModule ) {
|
|
|
|
if ( currentModule->aboutData() ) {
|
|
|
|
aboutModuleAction->setText(i18n("Help menu->about <modulename>", "About %1").tqarg(
|
|
|
|
currentModule->moduleInfo().moduleName().replace("&","&&")));
|
|
|
|
aboutModuleAction->setIcon(currentModule->moduleInfo().icon());
|
|
|
|
aboutModuleAction->setEnabled(true);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
resetModuleHelp();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::resetModuleHelp() {
|
|
|
|
aboutModuleAction->setText(i18n("About Current Module"));
|
|
|
|
aboutModuleAction->setIconSet(TQIconSet());
|
|
|
|
aboutModuleAction->setEnabled(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::widgetChange() {
|
|
|
|
TQString name;
|
|
|
|
if( groupWidget && groupWidget->currentModule()) {
|
|
|
|
name = groupWidget->currentModule()->moduleInfo().moduleName();
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !groupWidget ) {
|
|
|
|
setCaption( "" );
|
|
|
|
|
|
|
|
ModulesView *modulesView;
|
|
|
|
for( modulesView = modulesViewList.first(); modulesView; modulesView = modulesViewList.next()) {
|
|
|
|
modulesView->clearSelection();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotTopPage() {
|
|
|
|
KRadioAction *clickedRadioAction = (KRadioAction *)sender();
|
|
|
|
selectedPage = pageActions.find(clickedRadioAction);
|
|
|
|
|
|
|
|
KRadioAction *currentRadioAction;
|
|
|
|
for ( currentRadioAction = pageActions.first(); currentRadioAction; currentRadioAction = pageActions.next()) {
|
|
|
|
currentRadioAction->setChecked(currentRadioAction==clickedRadioAction);
|
|
|
|
}
|
|
|
|
|
|
|
|
windowStack->raiseWidget(overviewPages.at(selectedPage));
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotSearchHits(const TQString &query, int *hitList, int length) {
|
|
|
|
if(query=="") {
|
|
|
|
generalHitLabel->setText("");
|
|
|
|
advancedHitLabel->setText("");
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if(length>=1) {
|
|
|
|
generalHitLabel->setText(i18n("%1 hit in General","%1 hits in General",hitList[0]).tqarg(hitList[0]));
|
|
|
|
}
|
|
|
|
|
|
|
|
if(length>=2) {
|
|
|
|
advancedHitLabel->setText(i18n("%1 hit in Advanced","%1 hits in Advanced",hitList[1]).tqarg(hitList[1]));
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "mainwindow.moc"
|