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.
 
 
 
 
 
 

432 lines
11 KiB

  1. /*
  2. Copyright (c) 2000 Matthias Elter <elter@kde.org>
  3. Copyright (c) 2003 Daniel Molkentin <molkentin@kde.org>
  4. Copyright (c) 2003 Matthias Kretz <kretz@kde.org>
  5. Copyright (c) 2004 Frans Englich <frans.erglich.com>
  6. This library is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU Library General Public
  8. License as published by the Free Software Foundation; either
  9. version 2 of the License, or (at your option) any later version.
  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. You should have received a copy of the GNU Library General Public License
  15. along with this library; see the file COPYING.LIB. If not, write to
  16. the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
  17. Boston, MA 02110-1301, USA.
  18. */
  19. #include <tqcursor.h>
  20. #include <tqhbox.h>
  21. #include <tqlayout.h>
  22. #include <tqpushbutton.h>
  23. #include <kaboutdata.h>
  24. #include <kapplication.h>
  25. #include <kdebug.h>
  26. #include <kiconloader.h>
  27. #include <klibloader.h>
  28. #include <klocale.h>
  29. #include <kmessagebox.h>
  30. #include <kprocess.h>
  31. #include <krun.h>
  32. #include <kstdguiitem.h>
  33. #include <kuser.h>
  34. #include "kcmoduleloader.h"
  35. #include "kcmoduleproxy.h"
  36. #include "kcmultiwidget.h"
  37. /*
  38. Button usage:
  39. User1 => Reset
  40. User2 => Close
  41. User3 => Admin
  42. */
  43. class KCMultiWidget::KCMultiWidgetPrivate
  44. {
  45. public:
  46. KCMultiWidgetPrivate()
  47. : hasRootKCM( false ), currentModule( 0 )
  48. {}
  49. bool hasRootKCM;
  50. KCModuleProxy* currentModule;
  51. };
  52. KCMultiWidget::KCMultiWidget(TQWidget *parent, const char *name, bool modal)
  53. : KDialogBase(IconList, i18n("Configure"), Help | Default |Cancel | Apply |
  54. Ok | User1 | User2 | User3, Ok, parent, name, modal, true,
  55. KStdGuiItem::reset(), KStdGuiItem::close(), KStdGuiItem::adminMode())
  56. , dialogface( IconList ), d( new KCMultiWidgetPrivate )
  57. {
  58. init();
  59. }
  60. KCMultiWidget::KCMultiWidget( int dialogFace, TQWidget * parent, const char * name, bool modal )
  61. : KDialogBase( dialogFace, "Caption", Help | Default | Cancel | Apply | Ok |
  62. User1 | User2 | User3, Ok, parent, name, modal, true,
  63. KStdGuiItem::reset(), KStdGuiItem::close(), KStdGuiItem::adminMode())
  64. , dialogface( dialogFace ), d( new KCMultiWidgetPrivate )
  65. {
  66. init();
  67. }
  68. inline void KCMultiWidget::init()
  69. {
  70. connect( this, TQT_SIGNAL( finished()), TQT_SLOT( dialogClosed()));
  71. showButton( Ok, false );
  72. showButton( Cancel, false );
  73. showButton( User1, true ); // Reset button
  74. showButton( User2, true ); // Close button.
  75. showButton( User3, true); // Admin button.
  76. enableButton(Apply, false);
  77. enableButton(User1, false);
  78. connect(this, TQT_SIGNAL(aboutToShowPage(TQWidget *)), this, TQT_SLOT(slotAboutToShow(TQWidget *)));
  79. setInitialSize(TQSize(640,480));
  80. moduleParentComponents.setAutoDelete( true );
  81. }
  82. #include <kmessagebox.h>
  83. KCMultiWidget::~KCMultiWidget()
  84. {
  85. OrphanMap::Iterator end2 = m_orphanModules.end();
  86. for( OrphanMap::Iterator it = m_orphanModules.begin(); it != end2; ++it )
  87. delete ( *it );
  88. }
  89. void KCMultiWidget::slotDefault()
  90. {
  91. int curPageIndex = activePageIndex();
  92. ModuleList::Iterator end = m_modules.end();
  93. for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it )
  94. if( pageIndex( ( TQWidget * )( *it ).kcm->parent() ) == curPageIndex )
  95. {
  96. ( *it ).kcm->defaults();
  97. clientChanged( true );
  98. return;
  99. }
  100. }
  101. // Reset button.
  102. void KCMultiWidget::slotUser1()
  103. {
  104. int curPageIndex = activePageIndex();
  105. ModuleList::Iterator end = m_modules.end();
  106. for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it )
  107. if( pageIndex( ( TQWidget * )( *it ).kcm->parent() ) == curPageIndex )
  108. {
  109. ( *it ).kcm->load();
  110. clientChanged( false );
  111. return;
  112. }
  113. }
  114. void KCMultiWidget::apply()
  115. {
  116. TQStringList updatedModules;
  117. ModuleList::Iterator end = m_modules.end();
  118. for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it )
  119. {
  120. KCModuleProxy * m = ( *it ).kcm;
  121. if( m && m->changed() )
  122. {
  123. m->save();
  124. TQStringList * names = moduleParentComponents[ m ];
  125. kdDebug() << k_funcinfo << *names << " saved and added to the list" << endl;
  126. for( TQStringList::ConstIterator it = names->begin(); it != names->end(); ++it )
  127. if( updatedModules.find( *it ) == updatedModules.end() )
  128. updatedModules.append( *it );
  129. }
  130. }
  131. for( TQStringList::const_iterator it = updatedModules.begin(); it != updatedModules.end(); ++it )
  132. {
  133. kdDebug() << k_funcinfo << *it << " " << ( *it ).latin1() << endl;
  134. emit configCommitted( ( *it ).latin1() );
  135. }
  136. emit configCommitted();
  137. }
  138. void KCMultiWidget::slotApply()
  139. {
  140. TQPushButton *button = actionButton(Apply);
  141. if (button)
  142. button->setFocus();
  143. emit applyClicked();
  144. apply();
  145. }
  146. void KCMultiWidget::slotOk()
  147. {
  148. TQPushButton *button = actionButton(Ok);
  149. if (button)
  150. button->setFocus();
  151. emit okClicked();
  152. apply();
  153. accept();
  154. }
  155. void KCMultiWidget::slotHelp()
  156. {
  157. TQString docPath;
  158. int curPageIndex = activePageIndex();
  159. ModuleList::Iterator end = m_modules.end();
  160. for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it )
  161. if( pageIndex( ( TQWidget * )( *it ).kcm->parent() ) == curPageIndex )
  162. {
  163. docPath = ( *it ).kcm->moduleInfo().docPath();
  164. break;
  165. }
  166. KURL url( KURL("help:/"), docPath );
  167. if (url.protocol() == "help" || url.protocol() == "man" || url.protocol() == "info") {
  168. KProcess process;
  169. process << "khelpcenter"
  170. << url.url();
  171. process.start(KProcess::DontCare);
  172. process.detach();
  173. } else {
  174. new KRun(url);
  175. }
  176. }
  177. // Close button
  178. void KCMultiWidget::slotUser2() {
  179. emit close();
  180. }
  181. void KCMultiWidget::clientChanged(bool state)
  182. {
  183. kdDebug( 710 ) << k_funcinfo << state << endl;
  184. ModuleList::Iterator end = m_modules.end();
  185. for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it )
  186. if( ( *it ).kcm->changed() ) {
  187. enableButton( Apply, true );
  188. enableButton( User1, true);
  189. return;
  190. }
  191. enableButton( Apply, false );
  192. enableButton( User1, false);
  193. }
  194. void KCMultiWidget::addModule(const TQString& path, bool withfallback)
  195. {
  196. TQString complete = path;
  197. if( !path.endsWith( ".desktop" ))
  198. complete += ".desktop";
  199. KService::Ptr service = KService::serviceByStorageId( complete );
  200. addModule( KCModuleInfo( service ), TQStringList(), withfallback);
  201. }
  202. void KCMultiWidget::addModule(const KCModuleInfo& moduleinfo,
  203. TQStringList parentmodulenames, bool withfallback)
  204. {
  205. if( !moduleinfo.service() )
  206. return;
  207. if ( !kapp->authorizeControlModule( moduleinfo.service()->menuId() ))
  208. return;
  209. if( !KCModuleLoader::testModule( moduleinfo ))
  210. return;
  211. TQFrame* page = 0;
  212. if (!moduleinfo.service()->noDisplay())
  213. switch( dialogface )
  214. {
  215. case TreeList:
  216. parentmodulenames += moduleinfo.moduleName();
  217. page = addHBoxPage( parentmodulenames, moduleinfo.comment(),
  218. SmallIcon( moduleinfo.icon(),
  219. IconSize( KIcon::Small ) ) );
  220. break;
  221. case Tabbed:
  222. case IconList:
  223. page = addHBoxPage( moduleinfo.moduleName(),
  224. moduleinfo.comment(), DesktopIcon( moduleinfo.icon(),
  225. KIcon::SizeMedium ) );
  226. break;
  227. case Plain:
  228. page = plainPage();
  229. ( new TQHBoxLayout( page ) )->setAutoAdd( true );
  230. break;
  231. default:
  232. kdError( 710 ) << "unsupported dialog face for KCMultiWidget"
  233. << endl;
  234. break;
  235. }
  236. if(!page) {
  237. KCModuleLoader::unloadModule(moduleinfo);
  238. return;
  239. }
  240. KCModuleProxy * module;
  241. if( m_orphanModules.contains( moduleinfo.service() ) )
  242. {
  243. // the KCModule already exists - it was removed from the dialog in
  244. // removeAllModules
  245. module = m_orphanModules[ moduleinfo.service() ];
  246. m_orphanModules.remove( moduleinfo.service() );
  247. kdDebug( 710 ) << "Use KCModule from the list of orphans for " <<
  248. moduleinfo.moduleName() << ": " << module << endl;
  249. module->reparent( page, 0, TQPoint( 0, 0 ), true );
  250. if( module->changed() )
  251. clientChanged( true );
  252. if( activePageIndex() == -1 ) {
  253. showPage( pageIndex( page ) );
  254. }
  255. }
  256. else
  257. {
  258. module = new KCModuleProxy( moduleinfo, withfallback, page );
  259. TQStringList parentComponents = moduleinfo.service()->property(
  260. "X-KDE-ParentComponents" ).toStringList();
  261. moduleParentComponents.insert( module,
  262. new TQStringList( parentComponents ) );
  263. connect(module, TQT_SIGNAL(changed(bool)), this, TQT_SLOT(clientChanged(bool)));
  264. }
  265. CreatedModule cm;
  266. cm.kcm = module;
  267. cm.service = moduleinfo.service();
  268. cm.adminmode = false;
  269. cm.buttons = module->buttons();
  270. if ( moduleinfo.needsRootPrivileges() &&
  271. !KUser().isSuperUser() ) {/* If we're embedded, it's true */
  272. d->hasRootKCM = true;
  273. cm.adminmode = true;
  274. m_modules.append( cm );
  275. if( dialogface==Plain ) {
  276. slotAboutToShow( page ); // Won't be called otherwise, necessary for adminMode button
  277. }
  278. } else {
  279. m_modules.append( cm );
  280. }
  281. if( m_modules.count() == 1 ) {
  282. slotAboutToShow( page );
  283. }
  284. }
  285. KCModuleProxy * KCMultiWidget::currentModule() {
  286. if(d) {
  287. return d->currentModule;
  288. }
  289. return NULL;
  290. }
  291. void KCMultiWidget::applyOrRevert(KCModuleProxy * module){
  292. if( !module || !module->changed() )
  293. return;
  294. int res = KMessageBox::warningYesNo(this,
  295. i18n("There are unsaved changes in the active module.\n"
  296. "Do you want to apply the changes or discard them?"),
  297. i18n("Unsaved Changes"),
  298. KStdGuiItem::apply(),
  299. KStdGuiItem::discard());
  300. if (res == KMessageBox::Yes) {
  301. slotApply();
  302. } else {
  303. module->load();
  304. clientChanged( false );
  305. }
  306. }
  307. void KCMultiWidget::slotAboutToShow(TQWidget *page)
  308. {
  309. TQObject * obj = page->child( 0, "KCModuleProxy" );
  310. if( ! obj )
  311. return;
  312. KCModuleProxy *module = ( KCModuleProxy* )obj->qt_cast( "KCModuleProxy" );
  313. if( ! module )
  314. return;
  315. if( d && d->currentModule )
  316. applyOrRevert( d->currentModule );
  317. d->currentModule = module;
  318. emit ( aboutToShow( d->currentModule ) );
  319. ModuleList::Iterator end = m_modules.end();
  320. int buttons = 0;
  321. for( ModuleList::Iterator it = m_modules.begin(); it != end; ++it ) {
  322. if( ( *it ).kcm==d->currentModule) {
  323. showButton(User3, ( *it ).adminmode);
  324. buttons = ( *it ).buttons;
  325. }
  326. }
  327. showButton(Apply, buttons & KCModule::Apply);
  328. showButton(User1, buttons & KCModule::Apply); // Reset button.
  329. // Close button. No Apply button implies a Close button.
  330. showButton(User2, (buttons & KCModule::Apply)==0);
  331. enableButton( KDialogBase::Help, buttons & KCModule::Help );
  332. enableButton( KDialogBase::Default, buttons & KCModule::Default );
  333. disconnect( this, TQT_SIGNAL(user3Clicked()), 0, 0 );
  334. if (d->currentModule->moduleInfo().needsRootPrivileges() &&
  335. !d->currentModule->rootMode() )
  336. { /* Enable the Admin Mode button */
  337. enableButton( User3, true );
  338. connect( this, TQT_SIGNAL(user3Clicked()), d->currentModule, TQT_SLOT( runAsRoot() ));
  339. connect( this, TQT_SIGNAL(user3Clicked()), TQT_SLOT( disableRModeButton() ));
  340. } else {
  341. enableButton( User3, false );
  342. }
  343. }
  344. void KCMultiWidget::rootExit()
  345. {
  346. enableButton( User3, true);
  347. }
  348. void KCMultiWidget::disableRModeButton()
  349. {
  350. enableButton( User3, false );
  351. connect ( d->currentModule, TQT_SIGNAL( childClosed() ), TQT_SLOT( rootExit() ) );
  352. }
  353. void KCMultiWidget::slotCancel() {
  354. dialogClosed();
  355. KDialogBase::slotCancel();
  356. }
  357. void KCMultiWidget::dialogClosed()
  358. {
  359. if(d)
  360. {
  361. applyOrRevert(d->currentModule);
  362. }
  363. }
  364. #include "kcmultiwidget.moc"