TDE System Settings – easy to use control center
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

363 lines
12 KiB

  1. /**
  2. * This file is part of the System Settings package
  3. * Copyright (C) 2005 Benjamin C Meyer (ben+systempreferences at meyerhome dot net)
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Library General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Library General Public License
  16. * along with this library; see the file COPYING.LIB. If not, write to
  17. * the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
  18. * Boston, MA 02110-1301, USA.
  19. */
  20. #include "mainwindow.h"
  21. #include <kstdaction.h>
  22. #include <tqwhatsthis.h>
  23. #include <tqlabel.h>
  24. #include <tqvbox.h>
  25. #include <kaction.h>
  26. #include <tqtoolbutton.h>
  27. #include <klocale.h>
  28. #include <kservicegroup.h>
  29. #include <tqlayout.h>
  30. #include <tqwidgetstack.h>
  31. #include <tqtimer.h>
  32. #include <kiconloader.h>
  33. #include <kcmoduleloader.h>
  34. #include <kdialogbase.h>
  35. #include <kiconviewsearchline.h>
  36. #include <kapplication.h>
  37. #include <kaboutapplication.h>
  38. #include <kdebug.h>
  39. #include <kcmoduleproxy.h>
  40. #include <kbugreport.h>
  41. #include <kmenubar.h>
  42. #include <kactionclasses.h>
  43. #include <ktoolbarbutton.h>
  44. #include <tqtabbar.h>
  45. #include "kcmsearch.h"
  46. #include "modulesview.h"
  47. #include "moduleiconitem.h"
  48. #include "kcmodulemenu.h"
  49. #include "kcmultiwidget.h"
  50. MainWindow::MainWindow(bool embed, const TQString & menuFile,
  51. TQWidget *parent, const char *name) :
  52. KMainWindow(parent,name), menu(NULL), embeddedWindows(embed),
  53. groupWidget(NULL), selectedPage(0), dummyAbout(NULL) {
  54. // Load the menu structure in from disk.
  55. menu = new KCModuleMenu( menuFile );
  56. moduleTabs = new KTabWidget(this, "moduletabs",
  57. TQTabWidget::Top|TQTabWidget::Rounded);
  58. buildMainWidget();
  59. buildActions();
  60. setupGUI(ToolBar|Save|Create,TQString());
  61. widgetChange();
  62. }
  63. MainWindow::~MainWindow()
  64. {
  65. delete moduleTabs;
  66. delete windowStack;
  67. delete menu;
  68. delete dummyAbout;
  69. }
  70. void MainWindow::buildMainWidget()
  71. {
  72. windowStack = new TQWidgetStack( this, "widgetstack" );
  73. // Top level pages.
  74. TQValueList<MenuItem> subMenus = menu->menuList();
  75. TQValueList<MenuItem>::iterator it;
  76. KCScrollView *modulesScroller;
  77. moduleTabs->show();
  78. for ( it = subMenus.begin(); it != subMenus.end(); ++it ) {
  79. if( (*it).menu ) {
  80. modulesScroller = new KCScrollView(moduleTabs);
  81. ModulesView *modulesView = new ModulesView( menu, (*it).subMenu, modulesScroller->viewport(), "modulesView" );
  82. modulesViewList.append(modulesView);
  83. connect(modulesView, TQT_SIGNAL(itemSelected(TQIconViewItem* )), TQT_TQOBJECT(this), TQT_SLOT(slotItemSelected(TQIconViewItem*)));
  84. modulesScroller->addChild(modulesView);
  85. moduleTabs->addTab(modulesScroller, (*it).caption);
  86. overviewPages.append(modulesScroller);
  87. }
  88. }
  89. windowStack->addWidget(moduleTabs);
  90. windowStack->raiseWidget(moduleTabs);
  91. setCentralWidget(windowStack);
  92. }
  93. void MainWindow::buildActions()
  94. {
  95. KStdAction::quit(TQT_TQOBJECT(this), TQT_SLOT( close() ), actionCollection());
  96. resetModule = new KAction(i18n("Undo Changes"), 0, TQT_TQOBJECT(this),
  97. TQT_SLOT(showAllModules()), actionCollection(), "resetModule" );
  98. resetModule->setEnabled(false);
  99. defaultModule = new KAction(i18n("Reset to Defaults"), 0, TQT_TQOBJECT(this),
  100. TQT_SLOT(showAllModules()), actionCollection(), "defaultModule" );
  101. defaultModule->setEnabled(false);
  102. if( embeddedWindows ) {
  103. showAllAction = new KAction(i18n("Overview"), TQApplication::reverseLayout() ? "forward" : "back", 0, TQT_TQOBJECT(this),
  104. TQT_SLOT(showAllModules()), actionCollection(), "showAll" );
  105. showAllAction->setEnabled(false);
  106. }
  107. aboutModuleAction = new KAction(i18n("About Current Module"), 0, TQT_TQOBJECT(this), TQT_SLOT(aboutCurrentModule()), actionCollection(), "help_about_module");
  108. resetModuleHelp();
  109. // Search
  110. TQHBox *hbox = new TQHBox(0);
  111. hbox->setMaximumWidth( 400 );
  112. KcmSearch* search = new KcmSearch(&modulesViewList, hbox, "search");
  113. hbox->setStretchFactor(search,1);
  114. connect(search, TQT_SIGNAL(searchHits(const TQString &, int *, int)), TQT_TQOBJECT(this), TQT_SLOT(slotSearchHits(const TQString &, int *, int)));
  115. TQVBox *vbox = new TQVBox(hbox);
  116. generalHitLabel = new TQLabel(vbox);
  117. vbox->setStretchFactor(generalHitLabel,1);
  118. advancedHitLabel = new TQLabel(vbox);
  119. vbox->setStretchFactor(advancedHitLabel,1);
  120. hbox->setStretchFactor(vbox,1);
  121. // "Search:" label
  122. TQLabel *searchLabel = new TQLabel( this, "SearchLabel");
  123. searchLabel->setText( i18n("&Search:") );
  124. searchLabel->setFont(KGlobalSettings::toolBarFont());
  125. searchLabel->setMargin(2);
  126. searchText = new KWidgetAction( searchLabel, i18n("&Search:"), Key_F6, 0, 0, actionCollection(), "searchText" );
  127. searchLabel->setBuddy( search );
  128. // The search box.
  129. searchAction = new KWidgetAction( hbox, i18n( "Search System Settings" ), 0,
  130. 0, 0, actionCollection(), "search" );
  131. searchAction->setShortcutConfigurable( false );
  132. searchAction->setAutoSized( true );
  133. TQWhatsThis::add( search, i18n( "Search Bar<p>Enter a search term." ) );
  134. // The Clear search box button.
  135. KToolBarButton *clearWidget = new KToolBarButton(TQApplication::reverseLayout() ? "clear_left" : "locationbar_erase",
  136. 0, this);
  137. searchClear = new KWidgetAction( clearWidget, TQString(""), CTRL+Key_L, TQT_TQOBJECT(search), TQT_SLOT(clear()),
  138. actionCollection(), "searchReset");
  139. connect(clearWidget, TQT_SIGNAL(clicked()), searchClear, TQT_SLOT(activate()));
  140. searchClear->setWhatsThis( i18n( "Reset Search\n"
  141. "Resets the search so that "
  142. "all items are shown again." ) );
  143. // Top level pages.
  144. TQValueList<MenuItem> subMenus = menu->menuList();
  145. TQValueList<MenuItem>::iterator it;
  146. for ( it = subMenus.begin(); it != subMenus.end(); ++it ) {
  147. if( (*it).menu ) {
  148. KServiceGroup::Ptr group = KServiceGroup::group( (*it).subMenu );
  149. if ( !group ){
  150. kdDebug() << "Invalid Group \"" << (*it).subMenu << "\". Check your installation."<< endl;
  151. continue;
  152. }
  153. KRadioAction *newAction = new KRadioAction( group->caption(), group->icon(), KShortcut(), TQT_TQOBJECT(this),
  154. TQT_SLOT(slotTopPage()), actionCollection(), group->relPath() );
  155. pageActions.append(newAction);
  156. kdDebug() << "relpath is :" << group->relPath() << endl;
  157. }
  158. }
  159. pageActions.at(0)->setChecked(true);
  160. }
  161. void MainWindow::aboutCurrentModule()
  162. {
  163. if(!groupWidget)
  164. return;
  165. KCModuleProxy* module = groupWidget->currentModule();
  166. if( module && module->aboutData() ){
  167. KAboutApplication dlg( module->aboutData() );
  168. dlg.exec();
  169. }
  170. }
  171. void MainWindow::groupModulesFinished()
  172. {
  173. showAllModules();
  174. }
  175. void MainWindow::showAllModules()
  176. {
  177. windowStack->raiseWidget(moduleTabs);
  178. // Reset the widget for normal all widget viewing
  179. groupWidget = 0;
  180. widgetChange();
  181. if( embeddedWindows ) {
  182. showAllAction->setEnabled(false);
  183. }
  184. aboutModuleAction->setEnabled(false);
  185. searchText->setEnabled(true);
  186. searchClear->setEnabled(true);
  187. searchAction->setEnabled(true);
  188. KRadioAction *currentRadioAction;
  189. for ( currentRadioAction = pageActions.first(); currentRadioAction; currentRadioAction = pageActions.next()) {
  190. currentRadioAction->setEnabled(true);
  191. }
  192. resetModuleHelp();
  193. }
  194. void MainWindow::slotItemSelected( TQIconViewItem *item ){
  195. ModuleIconItem *mItem = (ModuleIconItem *)item;
  196. if( !mItem )
  197. return;
  198. groupWidget = moduleItemToWidgetDict.find(mItem);
  199. scrollView = moduleItemToScrollerDict.find(mItem);
  200. if(groupWidget==0) {
  201. TQValueList<KCModuleInfo> list = mItem->modules;
  202. KDialogBase::DialogType type = KDialogBase::IconList;
  203. if(list.count() == 1) {
  204. type=KDialogBase::Plain;
  205. }
  206. scrollView = new KCScrollView(windowStack);
  207. groupWidget = new KCMultiWidget(type, scrollView->viewport(), "moduleswidget");
  208. scrollView->addChild(groupWidget);
  209. windowStack->addWidget(scrollView);
  210. moduleItemToScrollerDict.insert(mItem,scrollView);
  211. moduleItemToWidgetDict.insert(mItem,groupWidget);
  212. connect(groupWidget, TQT_SIGNAL(aboutToShow( KCModuleProxy * )), TQT_TQOBJECT(this), TQT_SLOT(updateModuleHelp( KCModuleProxy * )));
  213. connect(groupWidget, TQT_SIGNAL(aboutToShowPage( TQWidget* )), TQT_TQOBJECT(this), TQT_SLOT(widgetChange()));
  214. connect(groupWidget, TQT_SIGNAL(finished()), TQT_TQOBJECT(this), TQT_SLOT(groupModulesFinished()));
  215. connect(groupWidget, TQT_SIGNAL(close()), TQT_TQOBJECT(this), TQT_SLOT(showAllModules()));
  216. TQValueList<KCModuleInfo>::iterator it;
  217. for ( it = list.begin(); it != list.end(); ++it ){
  218. qDebug("adding %s %s", (*it).moduleName().latin1(), (*it).fileName().latin1());
  219. groupWidget->addModule( *it );
  220. }
  221. groupWidget->reparent(scrollView->viewport(), 0, TQPoint());
  222. scrollView->reparent(windowStack, 0, TQPoint());
  223. }
  224. if( embeddedWindows ) {
  225. windowStack->raiseWidget( scrollView );
  226. setCaption( mItem->text() );
  227. showAllAction->setEnabled(true);
  228. searchText->setEnabled(false);
  229. searchClear->setEnabled(false);
  230. searchAction->setEnabled(false);
  231. KRadioAction *currentRadioAction;
  232. for ( currentRadioAction = pageActions.first(); currentRadioAction; currentRadioAction = pageActions.next()) {
  233. currentRadioAction->setEnabled(false);
  234. }
  235. } else {
  236. scrollView->show();
  237. }
  238. groupWidget->show();
  239. // We resize and expand the window if neccessary, but only once the window has been updated.
  240. // Some modules seem to dynamically change thier size. The new size is only available
  241. // once the dialog is updated. :-/ -SBE
  242. TQTimer::singleShot(0,this,TQT_SLOT(timerResize()));
  243. }
  244. void MainWindow::timerResize() {
  245. TQSize currentSize = size();
  246. TQSize newSize = currentSize.expandedTo(tqsizeHint());
  247. // Avoid resizing if possible.
  248. if(newSize!=currentSize) {
  249. resize(newSize);
  250. }
  251. }
  252. void MainWindow::updateModuleHelp( KCModuleProxy *currentModule ) {
  253. if ( currentModule->aboutData() ) {
  254. aboutModuleAction->setText(i18n("Help menu->about <modulename>", "About %1").tqarg(
  255. currentModule->moduleInfo().moduleName().replace("&","&&")));
  256. aboutModuleAction->setIcon(currentModule->moduleInfo().icon());
  257. aboutModuleAction->setEnabled(true);
  258. }
  259. else {
  260. resetModuleHelp();
  261. }
  262. }
  263. void MainWindow::resetModuleHelp() {
  264. aboutModuleAction->setText(i18n("About Current Module"));
  265. aboutModuleAction->setIconSet(TQIconSet());
  266. aboutModuleAction->setEnabled(false);
  267. }
  268. void MainWindow::widgetChange() {
  269. TQString name;
  270. if( groupWidget && groupWidget->currentModule()) {
  271. name = groupWidget->currentModule()->moduleInfo().moduleName();
  272. }
  273. if( !groupWidget ) {
  274. setCaption( "" );
  275. ModulesView *modulesView;
  276. for( modulesView = modulesViewList.first(); modulesView; modulesView = modulesViewList.next()) {
  277. modulesView->clearSelection();
  278. }
  279. }
  280. }
  281. void MainWindow::slotTopPage() {
  282. KRadioAction *clickedRadioAction = (KRadioAction *)sender();
  283. selectedPage = pageActions.find(clickedRadioAction);
  284. KRadioAction *currentRadioAction;
  285. for ( currentRadioAction = pageActions.first(); currentRadioAction; currentRadioAction = pageActions.next()) {
  286. currentRadioAction->setChecked(currentRadioAction==clickedRadioAction);
  287. }
  288. windowStack->raiseWidget(overviewPages.at(selectedPage));
  289. }
  290. void MainWindow::slotSearchHits(const TQString &query, int *hitList, int length) {
  291. if(query=="") {
  292. generalHitLabel->setText("");
  293. advancedHitLabel->setText("");
  294. } else {
  295. if(length>=1) {
  296. generalHitLabel->setText(i18n("%1 hit in General","%1 hits in General",hitList[0]).tqarg(hitList[0]));
  297. }
  298. if(length>=2) {
  299. advancedHitLabel->setText(i18n("%1 hit in Advanced","%1 hits in Advanced",hitList[1]).tqarg(hitList[1]));
  300. }
  301. }
  302. }
  303. #include "mainwindow.moc"