KShutdown – graphical shutdown utility
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.

956 lines
24KB

  1. /*
  2. mmainwindow.cpp - The main window
  3. Copyright (C) 2003 Konrad Twardowski <kdtonline@poczta.onet.pl>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  15. */
  16. #include "appobserver.h"
  17. #include "configuration.h"
  18. #include "confirmation.h"
  19. #include "extras.h"
  20. #include "miscutils.h"
  21. #include "mmainwindow.h"
  22. #include "mmessagedialog.h"
  23. #include "msettingsdialog.h"
  24. #include "mstatstab.h"
  25. #include "msystemtray.h"
  26. #include "progressbar.h"
  27. #include "systemconfig.h"
  28. #include <tqdatetimeedit.h>
  29. #include <tqfile.h>
  30. #include <tqhbox.h>
  31. #include <tqlabel.h>
  32. #include <tqlayout.h>
  33. #include <tqtimer.h>
  34. #include <tqtooltip.h>
  35. #include <tqvgroupbox.h>
  36. #include <tqwhatsthis.h>
  37. #include <dcopclient.h>
  38. #include <tdeaction.h>
  39. #include <kdebug.h>
  40. #include <kiconloader.h>
  41. #include <kglobalaccel.h>
  42. #include <kkeydialog.h>
  43. #include <tdelocale.h>
  44. #include <tdemenubar.h>
  45. #include <tdemessagebox.h>
  46. #include <knotifydialog.h>
  47. #include <tdepopupmenu.h>
  48. #include <kpushbutton.h>
  49. #include <twin.h>
  50. #include <kdesktopfile.h>
  51. #include <kmimetype.h>
  52. MMainWindow *MMainWindow::_instance = 0;
  53. MMainWindow::MMainWindow()
  54. // Iface
  55. : DCOPObject("KShutdownIface"),
  56. TDEMainWindow(0, "MMainWindow", WStyle_ContextHelp),
  57. _showMinimizeInfo(true),
  58. _oldSec(-1),
  59. _delayType(DelayType_Now)
  60. {
  61. _instance = this;
  62. connect(kapp, SIGNAL(aboutToQuit()), SLOT(slotAboutToQuit()));
  63. // init date/time
  64. dt_end = TQDateTime();
  65. dt_start = TQDateTime();
  66. // action timeout timer
  67. _timer = new TQTimer(this);
  68. connect(_timer, SIGNAL(timeout()), SLOT(slotCheckTime()));
  69. // init widgets
  70. setCentralWidget(initWidgets());
  71. initActions();
  72. initMainMenu();
  73. // init DCOP
  74. DCOPClient *client = kapp->dcopClient();
  75. client->registerAs(kapp->name(), false);
  76. client->setDefaultObject(objId()); // KShutdownIface
  77. TDEConfig *config = kapp->config();
  78. config->setGroup("Extras");
  79. TQString extrasCommand = config->readEntry("Command", TQString::null);
  80. TQString extrasDescription = config->readEntry("Description", TQString::null);
  81. if (!extrasCommand.isEmpty() || TQFile::exists(extrasCommand)) {
  82. setAction(Action::Extras);
  83. TQIconSet extrasIcon;
  84. TQString mimeType;
  85. mimeType = KMimeType::findByPath(extrasCommand)->name();
  86. if (mimeType != "application/x-desktop")
  87. extrasIcon = TQIconSet(KMimeType::pixmapForURL(KURL::fromPathOrURL(extrasCommand)));
  88. else {
  89. // application/x-desktop
  90. KDesktopFile *desktopFile = new KDesktopFile(extrasCommand, true);
  91. if (desktopFile->getConfigState() != TDEConfigBase::NoAccess)
  92. extrasIcon = TQIconSet(SmallIcon(desktopFile->readIcon()));
  93. delete desktopFile;
  94. }
  95. ks_extras->setAction(extrasCommand, extrasDescription, &extrasIcon);
  96. }
  97. else {
  98. setAction((Action::Type)kshutdownrc->generalAction);
  99. }
  100. setDelayType((DelayType)kshutdownrc->generalDelayType);
  101. MSystemTray::setMode((MSystemTray::Mode)kshutdownrc->systemTray);
  102. setCaptions();
  103. slotUpdateTimeInfo();
  104. setFixedHeight(layout()->minimumSize().height());
  105. }
  106. MMainWindow::~MMainWindow()
  107. {
  108. TDEConfig *config = kapp->config();
  109. config->setGroup("Extras");
  110. config->writeEntry("Command", ks_extras->fileToExecute());
  111. config->writeEntry("Description", ks_extras->getActionDescription());
  112. // TODO: 2.0: remember/restore time
  113. kshutdownrc->generalAction = ks_actions->current();
  114. kshutdownrc->generalDelayType = cb_delayTypes->currentItem();
  115. kshutdownrc->writeConfig();
  116. }
  117. void MMainWindow::setDelayType(const DelayType value)
  118. {
  119. // kdDebug() << "MMainWindow::setDelayType: " << value << endl;
  120. if (MiscUtils::isRestricted("tab_time"))
  121. {
  122. _delayType = DelayType_Now;
  123. cb_delayTypes->setEnabled(false);
  124. }
  125. else
  126. {
  127. _delayType = value;
  128. cb_delayTypes->setEnabled(true);
  129. }
  130. cb_delayTypes->setCurrentItem(_delayType);
  131. switch (_delayType)
  132. {
  133. case DelayType_Now:
  134. _dateTimeEdit->dateEdit()->setEnabled(false);
  135. _dateTimeEdit->timeEdit()->setEnabled(false);
  136. _dateTimeEdit->show();
  137. _appObserver->hide();
  138. l_statusLine->hide();
  139. break;
  140. case DelayType_TimeFromNow:
  141. TQWhatsThis::add(_dateTimeEdit, i18n("Enter hour and minute."));
  142. _dateTimeEdit->dateEdit()->setEnabled(false);
  143. _dateTimeEdit->timeEdit()->setEnabled(true);
  144. _dateTimeEdit->timeEdit()->setDisplay(TQTimeEdit::Hours | TQTimeEdit::Minutes);
  145. _dateTimeEdit->timeEdit()->setTime(TQTime());
  146. _dateTimeEdit->show();
  147. _appObserver->hide();
  148. l_statusLine->show();
  149. break;
  150. case DelayType_DateTime:
  151. TQWhatsThis::add(_dateTimeEdit, i18n("Enter date and time."));
  152. _dateTimeEdit->dateEdit()->setEnabled(true);
  153. _dateTimeEdit->timeEdit()->setEnabled(true);
  154. _dateTimeEdit->timeEdit()->setDisplay(
  155. TDEGlobal::locale()->use12Clock()
  156. ? (TQTimeEdit::Hours | TQTimeEdit::Minutes | TQTimeEdit::AMPM)
  157. : (TQTimeEdit::Hours | TQTimeEdit::Minutes)
  158. );
  159. _dateTimeEdit->dateEdit()->setDate(TQDate::currentDate());
  160. _dateTimeEdit->timeEdit()->setTime(TQTime::currentTime());
  161. _dateTimeEdit->show();
  162. _appObserver->hide();
  163. l_statusLine->show();
  164. break;
  165. case DelayType_OnAppExit:
  166. _dateTimeEdit->hide();
  167. _appObserver->show();
  168. _appObserver->refresh();
  169. l_statusLine->hide();
  170. break;
  171. }
  172. }
  173. void MMainWindow::setTime(const TQTime &time)
  174. {
  175. _dateTimeEdit->timeEdit()->setTime(TQTime(time.hour(), time.minute(), 0));
  176. }
  177. void MMainWindow::setAction(const Action::Type action)
  178. {
  179. // kdDebug() << "MMainWindow::setAction: " << ks_actions->getName(action) << endl;
  180. if (!ks_actions->isEnabled(action))
  181. {
  182. // FIXME: 2.0: "Start" button incorectly disabled/enabled after config change
  183. // FIXME: 2.0: confusing
  184. _startAction->setEnabled(false);
  185. return;
  186. }
  187. _startAction->setEnabled(true);
  188. ks_actions->setCurrent(action);
  189. cb_actions->setCurrentItem(action - 1);
  190. switch (action)
  191. {
  192. case Action::Nothing:
  193. case Action::ShutDown:
  194. case Action::Reboot:
  195. case Action::LockScreen:
  196. case Action::Logout:
  197. ks_extras->button()->hide();
  198. break;
  199. case Action::Extras:
  200. ks_extras->button()->show();
  201. break;
  202. }
  203. }
  204. void MMainWindow::setDate(const TQDate &date)
  205. {
  206. _dateTimeEdit->dateEdit()->setDate(date);
  207. }
  208. void MMainWindow::start(const bool confirmation) {
  209. if (ks_actions->active())
  210. return;
  211. // kdDebug() << "MMainWindow::start" << endl;
  212. // check if selected process still exists
  213. if ((_delayType == DelayType_OnAppExit) && !_appObserver->isValid())
  214. return;
  215. // display information if user didn't selected any "extras" command
  216. if ((ks_actions->current() == Action::Extras) && ks_extras->fileToExecute().isNull())
  217. {
  218. KMessageBox::information(
  219. this,
  220. MiscUtils::HTML(i18n("Click the <b>Select a command...</b> button first."))
  221. );
  222. return;
  223. }
  224. if (confirmation)
  225. {
  226. if (!Confirmation::confirm(ks_actions->current(), getTimeInfo()))
  227. return; // action not confirmed by user; do nothing
  228. }
  229. // immediate action
  230. if (
  231. (_delayType == DelayType_Now) ||
  232. (
  233. (_delayType == DelayType_TimeFromNow) &&
  234. (_dateTimeEdit->timeEdit()->time().hour() == 0) &&
  235. (_dateTimeEdit->timeEdit()->time().minute() == 0)
  236. )
  237. )
  238. {
  239. ks_actions->execCurrent();
  240. return;
  241. }
  242. ks_actions->setActive(true);
  243. MSystemTray::setMode((MSystemTray::Mode)kshutdownrc->systemTray);
  244. setWidgetsEnabled(false); // disable widgets
  245. slotUpdateTimeInfo();
  246. _oldSec = -1;
  247. if (MSystemTray::isInstance())
  248. ks_tray->setActive(true);
  249. if ((_delayType != DelayType_OnAppExit) && (dt_end < dt_start))
  250. {
  251. TQString selDT = i18n("Selected date/time: %1").arg("<b>" + TDEGlobal::locale()->formatDateTime(dt_end, false, true)+ "</b>");
  252. TQString curDT = i18n("Current date/time: %1").arg("<b>" + TDEGlobal::locale()->formatDateTime(dt_start, false, true) + "</b>");
  253. cancel();
  254. KMessageBox::error(
  255. 0,
  256. MiscUtils::HTML(
  257. i18n("Selected date/time is earlier than current date/time!") +
  258. "<br><br>" +
  259. selDT + "<br>" +
  260. curDT + "<br>" \
  261. "<br>" +
  262. i18n("Action cancelled!")
  263. )
  264. );
  265. return;
  266. }
  267. int secsTo = dt_start.secsTo(dt_end);
  268. // setup progress bar
  269. if (kshutdownrc->progressBarEnabled) {
  270. ProgressBar *progressBar = ProgressBar::getInstance();
  271. progressBar->setValues(0, secsTo);
  272. progressBar->show();
  273. }
  274. if (_delayType == DelayType_OnAppExit)
  275. {
  276. _timer->start(2000);
  277. setCaptions(TQString::null, _appObserver->getInfo());
  278. }
  279. else
  280. {
  281. _timer->start(500); // this timer value is good ..
  282. updateTimeInfo(secsTo);
  283. }
  284. }
  285. void MMainWindow::cancel()
  286. {
  287. MMessageDialog::cancel();
  288. if (!ks_actions->active() && (_delayType != DelayType_OnAppExit))
  289. return;
  290. // kdDebug() << "MMainWindow::cancel" << endl;
  291. ks_actions->setActive(false);
  292. MSystemTray::setMode((MSystemTray::Mode)kshutdownrc->systemTray);
  293. _timer->stop();
  294. setCaptions();
  295. if (MSystemTray::isInstance())
  296. ks_tray->setActive(false);
  297. ProgressBar::freeInstance();
  298. setWidgetsEnabled(true);
  299. // TODO: 2.0: MiscUtils::customMessage(i18n("Action cancelled!"));
  300. }
  301. bool MMainWindow::shutDown()
  302. {
  303. return ks_actions->exec(Action::ShutDown);
  304. }
  305. bool MMainWindow::shutdown()
  306. {
  307. return shutDown();
  308. //.........^^
  309. }
  310. bool MMainWindow::reboot()
  311. {
  312. return ks_actions->exec(Action::Reboot);
  313. }
  314. bool MMainWindow::lockScreen()
  315. {
  316. return ks_actions->exec(Action::LockScreen, false);
  317. }
  318. bool MMainWindow::logout()
  319. {
  320. return ks_actions->exec(Action::Logout);
  321. }
  322. void MMainWindow::configure()
  323. {
  324. if (MSettingsDialog::isActive())
  325. return;
  326. new MSettingsDialog(this);
  327. MSettingsDialog::freeInstance();
  328. _showMinimizeInfo = true;
  329. }
  330. TQString MMainWindow::getStatusInfo()
  331. {
  332. return caption();
  333. }
  334. void MMainWindow::makeInvisible() {
  335. if (MSystemTray::isInstance())
  336. ks_tray->hide();
  337. hide();
  338. }
  339. void MMainWindow::makeVisible()
  340. {
  341. MSystemTray::setMode((MSystemTray::Mode)kshutdownrc->systemTray);
  342. show();
  343. WId id = winId();
  344. KWin::setOnDesktop(id, KWin::currentDesktop());
  345. KWin::deIconifyWindow(id);
  346. raise();
  347. }
  348. void MMainWindow::setTestMode(bool yes)
  349. {
  350. if (ks_actions->testMode() == yes)
  351. return;
  352. ks_actions->setTestMode(yes);
  353. setCaptions(); // add/remove "[ TEST MODE ]" to/from window caption.
  354. MiscUtils::customMessage(ks_actions->testMode() ? i18n("Test mode enabled") : i18n("Test mode disabled"));
  355. }
  356. TQString MMainWindow::getTimeInfo()
  357. {
  358. // start time = now
  359. dt_start.setDate(TQDate::currentDate());
  360. dt_start.setTime(TQTime::currentTime());
  361. // end time = start time
  362. dt_end.setDate(dt_start.date());
  363. dt_end.setTime(dt_start.time());
  364. // round down msec
  365. int ms = dt_end.time().msec();
  366. if (ms > 0)
  367. dt_end.setTime(dt_end.time().addMSecs(-ms));
  368. switch (_delayType)
  369. {
  370. case DelayType_Now:
  371. case DelayType_OnAppExit:
  372. break;
  373. case DelayType_TimeFromNow:
  374. // end time = start time + delay time
  375. dt_end = dt_end.addSecs(
  376. (_dateTimeEdit->timeEdit()->time().hour() * 3600) +
  377. (_dateTimeEdit->timeEdit()->time().minute() * 60)
  378. );
  379. break;
  380. case DelayType_DateTime:
  381. // end time = selected date/time
  382. dt_end.setDate(_dateTimeEdit->dateEdit()->date());
  383. dt_end.setTime(_dateTimeEdit->timeEdit()->time());
  384. break;
  385. }
  386. if (_delayType == DelayType_Now)
  387. return i18n("No Delay");
  388. if (_delayType == DelayType_OnAppExit)
  389. return TQString::null;
  390. return MiscUtils::formatDateTime(dt_end.addSecs(1));
  391. }
  392. void MMainWindow::initMainMenu()
  393. {
  394. KMenuBar *mainMenu = menuBar();
  395. // file
  396. TDEPopupMenu *pm_file = new TDEPopupMenu(this);
  397. _statisticsAction->plug(pm_file);
  398. pm_file->insertSeparator();
  399. if (MiscUtils::isRestricted("tab_stats"))
  400. _statisticsAction->setEnabled(false);
  401. // TODO: 2.0: improve kiosk support
  402. KStdAction::quit(this, SLOT(slotQuit()), actionCollection())->plug(pm_file);
  403. mainMenu->insertItem(i18n("&File"), pm_file);
  404. // actions
  405. TDEPopupMenu *pm_actions = new TDEPopupMenu(this);
  406. pm_actions->insertTitle(SmallIcon("messagebox_warning"), i18n("No Delay"));
  407. _shutDownAction->plug(pm_actions);
  408. _rebootAction->plug(pm_actions);
  409. _lockScreenAction->plug(pm_actions);
  410. _logoutAction->plug(pm_actions);
  411. pm_actions->insertSeparator();
  412. _cancelAction->plug(pm_actions);
  413. mainMenu->insertItem(i18n("&Actions"), pm_actions);
  414. // settings
  415. TDEPopupMenu *pm_settings = new TDEPopupMenu(this);
  416. _checkSystemConfigurationAction->plug(pm_settings);
  417. pm_settings->insertSeparator();
  418. pm_settings->insertItem(SmallIcon("configure_shortcuts"), i18n("Configure Global Shortcuts..."), this, SLOT(slotConfigureGlobalShortcuts()));
  419. KStdAction::keyBindings(this, SLOT(slotConfigureShortcuts()), actionCollection())->plug(pm_settings);
  420. pm_settings->insertSeparator();
  421. KStdAction::configureNotifications(this, SLOT(slotConfigureNotifications()), actionCollection())->plug(pm_settings);
  422. _configureKShutDownAction->plug(pm_settings);
  423. mainMenu->insertItem(i18n("&Settings"), pm_settings);
  424. // help
  425. mainMenu->insertItem(SmallIcon("help"), i18n("&Help"), helpMenu());
  426. }
  427. void MMainWindow::initActions()
  428. {
  429. // shut down actions
  430. ac_shutDown = new TDEActionCollection(this, this);
  431. _lockScreenAction = new TDEAction(
  432. ks_actions->getName(Action::LockScreen),
  433. ks_actions->getIcon(Action::LockScreen), TDEShortcut(),
  434. ks_actions, SLOT(slotLockScreen()),
  435. ac_shutDown, "kshutdown_lockscreen"
  436. );
  437. _logoutAction = new TDEAction(
  438. ks_actions->getName(Action::Logout),
  439. ks_actions->getIcon(Action::Logout), TDEShortcut(),
  440. ks_actions, SLOT(slotLogout()),
  441. ac_shutDown, "kshutdown_logout"
  442. );
  443. _rebootAction = new TDEAction(
  444. ks_actions->getName(Action::Reboot),
  445. ks_actions->getIcon(Action::Reboot), TDEShortcut(),
  446. ks_actions, SLOT(slotReboot()),
  447. ac_shutDown, "kshutdown_reboot"
  448. );
  449. _shutDownAction = new TDEAction(
  450. ks_actions->getName(Action::ShutDown),
  451. ks_actions->getIcon(Action::ShutDown), TDEShortcut(),
  452. ks_actions, SLOT(slotShutDown()),
  453. ac_shutDown, "kshutdown_shutdown"
  454. );
  455. // standard actions
  456. _cancelAction = new TDEAction(
  457. i18n("C&ancel"),
  458. "cancel", TDEShortcut(Key_Escape),
  459. this, SLOT(slotCancel()),
  460. actionCollection(), "kshutdown_cancelaction"
  461. );
  462. _cancelAction->setEnabled(false);
  463. _checkSystemConfigurationAction = new TDEAction(
  464. i18n("Check &System Configuration"),
  465. "button_ok", TDEShortcut(),
  466. this, SLOT(slotCheckSystemConfig()),
  467. actionCollection(), "kshutdown_checksystemconfiguration"
  468. );
  469. _configureKShutDownAction = KStdAction::preferences(this, SLOT(slotConfigureKShutDown()), actionCollection());
  470. _startAction = new TDEAction(
  471. i18n("&Start"),
  472. "button_ok", TDEShortcut(Key_Return),
  473. this, SLOT(slotStart()),
  474. actionCollection(), "kshutdown_startaction"
  475. );
  476. MiscUtils::plug(_startAction, b_startStop);
  477. _statisticsAction = new TDEAction(
  478. i18n("&Statistics"),
  479. TDEShortcut(Key_F2),
  480. this, SLOT(slotStats()),
  481. actionCollection(), "kshutdown_statistics"
  482. );
  483. actionCollection()->readShortcutSettings();
  484. ac_shutDown->readShortcutSettings();
  485. // init global actions/shortcuts
  486. _globalAccel = new TDEGlobalAccel(this);
  487. _globalAccel->insert(
  488. "kshutdown_shutdown",
  489. ks_actions->getName(Action::ShutDown),
  490. TQString(),
  491. 0, 0, ks_actions, SLOT(slotShutDown())
  492. );
  493. _globalAccel->insert(
  494. "kshutdown_reboot",
  495. ks_actions->getName(Action::Reboot),
  496. TQString(),
  497. 0, 0, ks_actions, SLOT(slotReboot())
  498. );
  499. _globalAccel->insert(
  500. "kshutdown_lockscreen",
  501. ks_actions->getName(Action::LockScreen),
  502. TQString(),
  503. 0, 0, ks_actions, SLOT(slotLockScreen())
  504. );
  505. _globalAccel->insert(
  506. "kshutdown_logout",
  507. ks_actions->getName(Action::Logout),
  508. TQString(),
  509. 0, 0, ks_actions, SLOT(slotLogout())
  510. );
  511. _globalAccel->readSettings();
  512. _globalAccel->updateConnections();
  513. }
  514. TQWidget *MMainWindow::initWidgets()
  515. {
  516. TQWidget *w = new TQWidget(this);
  517. TQVBoxLayout *l = new TQVBoxLayout(w, 5);
  518. TQVGroupBox *gb_actions = new TQVGroupBox(i18n("Select an &action to perform"), w);
  519. gb_actions->setInsideSpacing(0);
  520. // actions combo box
  521. cb_actions = new TQComboBox(gb_actions, "TQComboBox::cb_actions");
  522. cb_actions->setFocusPolicy(StrongFocus);
  523. cb_actions->insertItem(ks_actions->getIcon(Action::ShutDown), ks_actions->getName(Action::ShutDown));
  524. cb_actions->insertItem(ks_actions->getIcon(Action::Reboot), ks_actions->getName(Action::Reboot));
  525. cb_actions->insertItem(ks_actions->getIcon(Action::LockScreen), ks_actions->getName(Action::LockScreen));
  526. cb_actions->insertItem(ks_actions->getIcon(Action::Logout), ks_actions->getName(Action::Logout));
  527. cb_actions->insertItem(ks_actions->getIcon(Action::Extras), i18n("Extras"));
  528. TQWhatsThis::add(cb_actions, i18n("Select an action to perform at the selected time."));
  529. connect(cb_actions, SIGNAL(activated(int)), SLOT(slotActionChange(int)));
  530. // extras
  531. ks_extras->createButton(gb_actions);
  532. TQVGroupBox *gb_delayValues = new TQVGroupBox(i18n("S&elect a time"), w);
  533. gb_delayValues->setInsideSpacing(0);
  534. // delay type combo box
  535. cb_delayTypes = new TQComboBox(gb_delayValues, "TQComboBox::cb_delayTypes");
  536. cb_delayTypes->setFocusPolicy(StrongFocus);
  537. cb_delayTypes->insertItem(SmallIcon("messagebox_warning"), i18n("No Delay"));
  538. cb_delayTypes->insertItem(SmallIcon("clock"), i18n("Time From Now (HH:MM)"));
  539. cb_delayTypes->insertItem(SmallIcon("date"), i18n("At Date/Time"));
  540. cb_delayTypes->insertItem(SmallIcon("misc"), i18n("When selected application exit"));
  541. if (MiscUtils::isRestricted("tab_time"))
  542. TQWhatsThis::add(cb_delayTypes, i18n("Disabled by the Administrator."));
  543. else
  544. TQWhatsThis::add(cb_delayTypes, i18n("Select the type of delay."));
  545. connect(cb_delayTypes, SIGNAL(activated(int)), SLOT(slotDelayTypeChange(int)));
  546. // date/time edit
  547. _dateTimeEdit = new TQDateTimeEdit(gb_delayValues, "TQDateTimeEdit::_dateTimeEdit");
  548. _dateTimeEdit->setAutoAdvance(true);
  549. _dateTimeEdit->dateEdit()->setMinValue(TQDate::currentDate());
  550. setDate(TQDate::currentDate());
  551. connect(_dateTimeEdit, SIGNAL(valueChanged(const TQDateTime &)), SLOT(slotUpdateTimeInfo()));
  552. // app observer/killer
  553. _appObserver = new AppObserver(gb_delayValues);
  554. // status line
  555. l_statusLine = new TQLabel(gb_delayValues);
  556. TQWhatsThis::add(l_statusLine, i18n("Selected time."));
  557. l->addWidget(gb_actions);
  558. l->addWidget(gb_delayValues);
  559. l->addStretch(5);
  560. // start/stop action button
  561. b_startStop = new KPushButton(w, "KPushButton::b_startStop");
  562. b_startStop->setSizePolicy(TQSizePolicy(TQSizePolicy::MinimumExpanding, TQSizePolicy::Fixed));
  563. b_startStop->setDefault(true); // enter key
  564. l->addWidget(b_startStop);
  565. return w;
  566. }
  567. void MMainWindow::setCaptions(const TQString &remainingTime, const TQString &selectedTime)
  568. {
  569. // window tool tip
  570. TQString s;
  571. if (ks_actions->active())
  572. {
  573. if (remainingTime.isNull())
  574. s = selectedTime + " > " + ks_actions->getCurrentName();
  575. else
  576. s = remainingTime + " > " + selectedTime + " - " + ks_actions->getCurrentName();
  577. }
  578. if (ks_actions->testMode())
  579. s += " [" + i18n("TEST MODE") + "]";
  580. setCaption(s);
  581. // system tray tool tip
  582. if (ks_actions->active()) {
  583. s = "<br>";
  584. s += i18n("Remaining time: <b>%1</b>").arg(remainingTime.isNull() ? i18n("Unknown") : remainingTime) + "<br>";
  585. s += i18n("Selected time: <b>%1</b>").arg(selectedTime) + "<br>";
  586. s += i18n("Selected action: <b>%1</b>").arg(ks_actions->getCurrentName()) + "<br>";
  587. if (ks_actions->testMode())
  588. {
  589. s += "<br>" + i18n("<b>Note: </b> The test mode is enabled") + "<br>";
  590. }
  591. }
  592. else {
  593. s = "";
  594. }
  595. if (MSystemTray::isInstance()) {
  596. TQToolTip::add(
  597. ks_tray,
  598. MiscUtils::HTML("<b>KShutDown</b><br>" + s)
  599. );
  600. }
  601. if (ProgressBar::isInstance()) {
  602. TQToolTip::add(
  603. ProgressBar::getInstance(),
  604. MiscUtils::HTML("<b>KShutDown</b><br>" + s)
  605. );
  606. }
  607. }
  608. void MMainWindow::setWidgetsEnabled(const bool yes)
  609. {
  610. cb_delayTypes->setEnabled(yes);
  611. _dateTimeEdit->setEnabled(yes);
  612. cb_actions->setEnabled(yes);
  613. ks_extras->button()->setEnabled(yes);
  614. _appObserver->setWidgetsEnabled(yes);
  615. // actions
  616. _cancelAction->setEnabled(!yes);
  617. _startAction->setEnabled(yes);
  618. if (yes)
  619. MiscUtils::plug(_startAction, b_startStop);
  620. else
  621. MiscUtils::plug(_cancelAction, b_startStop);
  622. }
  623. void MMainWindow::updateTimeInfo(const int secs)
  624. {
  625. setCaptions(
  626. MiscUtils::formatDateTime(secs),
  627. TDEGlobal::locale()->formatDateTime(dt_end, true, true)
  628. );
  629. // update progress bar
  630. if (ProgressBar::isInstance()) {
  631. ProgressBar *progressBar = ProgressBar::getInstance();
  632. progressBar->setProgress(secs);
  633. }
  634. }
  635. void MMainWindow::slotCancel()
  636. {
  637. cancel();
  638. }
  639. void MMainWindow::slotStart() {
  640. start(true);
  641. }
  642. void MMainWindow::slotQuit()
  643. {
  644. ks_actions->setTotalExit(true); // do not hide window in the system tray
  645. close();
  646. }
  647. void MMainWindow::slotAboutToQuit()
  648. {
  649. ks_actions->setTotalExit(true);
  650. }
  651. void MMainWindow::slotCheckTime()
  652. {
  653. // check process
  654. if (_delayType == DelayType_OnAppExit)
  655. {
  656. if (!_appObserver->isSelectedProcessRunning()) {
  657. // restore window
  658. makeVisible();
  659. // show warning message
  660. if (kshutdownrc->warningMessageEnabled)
  661. {
  662. cancel();
  663. if (MMessageDialog::show(30))
  664. ks_actions->execCurrent();
  665. }
  666. else
  667. {
  668. ks_actions->totalExec();
  669. }
  670. }
  671. return;
  672. }
  673. // check timeout
  674. TQDateTime now = TQDateTime::currentDateTime();
  675. int curSec = now.time().second();
  676. if (curSec == _oldSec)
  677. return; // time not changed since last check
  678. _oldSec = curSec;
  679. // timeout
  680. if (now >= dt_end)
  681. {
  682. // restore window
  683. makeVisible();
  684. ks_actions->totalExec();
  685. return;
  686. }
  687. int secsTo = now.secsTo(dt_end);
  688. updateTimeInfo(secsTo);
  689. // show warning message
  690. if (
  691. kshutdownrc->warningMessageEnabled &&
  692. (secsTo <= (kshutdownrc->warningMessageDelay * 60))
  693. )
  694. {
  695. // restore window
  696. makeVisible();
  697. // show warning message dialog
  698. cancel();
  699. if (MMessageDialog::show(secsTo))
  700. ks_actions->execCurrent();
  701. return;
  702. }
  703. MiscUtils::notifyUser(secsTo);
  704. }
  705. void MMainWindow::slotDelayTypeChange(int index) {
  706. setDelayType((DelayType)index);
  707. slotUpdateTimeInfo();
  708. }
  709. void MMainWindow::slotConfigureGlobalShortcuts() {
  710. if (KKeyDialog::configure(_globalAccel, false, this)) {
  711. _globalAccel->writeSettings(0, true);
  712. _globalAccel->updateConnections();
  713. }
  714. }
  715. void MMainWindow::slotConfigureKShutDown() {
  716. configure();
  717. }
  718. void MMainWindow::slotConfigureNotifications() {
  719. KNotifyDialog::configure(this);
  720. }
  721. void MMainWindow::slotConfigureShortcuts()
  722. {
  723. KKeyDialog *dialog = new KKeyDialog(false, this);
  724. dialog->insert(actionCollection());
  725. dialog->insert(ac_shutDown);
  726. dialog->configure(true);
  727. delete dialog;
  728. actionCollection()->writeShortcutSettings();
  729. ac_shutDown->writeShortcutSettings();
  730. }
  731. void MMainWindow::slotActionChange(int index)
  732. {
  733. setAction((Action::Type)(index + 1)); // 0 = What_Nothing
  734. if (ks_actions->current() != Action::Extras)
  735. ks_extras->setAction(TQString::null, TQString::null);
  736. }
  737. void MMainWindow::slotCheckSystemConfig()
  738. {
  739. SystemConfig::check(this);
  740. }
  741. void MMainWindow::slotStats()
  742. {
  743. if (!MiscUtils::isRestricted("tab_stats"))
  744. MStatsTab::getInstance()->show();
  745. }
  746. void MMainWindow::slotUpdateTimeInfo()
  747. {
  748. l_statusLine->setText("<b>" + getTimeInfo() + "</b>");
  749. }
  750. bool MMainWindow::queryClose()
  751. {
  752. // exit
  753. if (ks_actions->totalExit() || kapp->sessionSaving())
  754. return true;
  755. // MSystemTray::Always
  756. if (kshutdownrc->systemTray == MSystemTray::Always)
  757. {
  758. if (_showMinimizeInfo) {
  759. MiscUtils::passiveMessage(
  760. i18n("KShutDown has been minimized"),
  761. ks_tray
  762. );
  763. _showMinimizeInfo = false;
  764. }
  765. ks_tray->flashIcon();
  766. hide();
  767. return false;
  768. }
  769. // MSystemTray::IfActive
  770. if (kshutdownrc->systemTray == MSystemTray::IfActive)
  771. {
  772. if (ks_actions->active())
  773. {
  774. if (_showMinimizeInfo) {
  775. MiscUtils::passiveMessage(
  776. i18n("KShutDown has been minimized"),
  777. ks_tray
  778. );
  779. _showMinimizeInfo = false;
  780. }
  781. ks_tray->flashIcon();
  782. hide();
  783. return false;
  784. }
  785. else {
  786. // FIXME: 2.0: quit message
  787. MiscUtils::passiveMessage(i18n("KShutDown has quit"));
  788. return true;
  789. }
  790. }
  791. // MSystemTray::Never
  792. if (kshutdownrc->systemTray == MSystemTray::Never) {
  793. // FIXME: 2.0: quit message
  794. MiscUtils::passiveMessage(i18n("KShutDown has quit"));
  795. return true;
  796. }
  797. return true;
  798. }
  799. bool MMainWindow::queryExit()
  800. {
  801. ks_actions->setTotalExit(true);
  802. return true; // ok to exit
  803. }
  804. #include "mmainwindow.moc"