PageRenderTime 57ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/CMain.cpp

https://bitbucket.org/skynowa/start
C++ | 2264 lines | 1636 code | 373 blank | 255 comment | 105 complexity | f3ce89ba9bd20af46d091e51c19c0b1a MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /**
  2. * \file CMain.h
  3. * \brief main window
  4. */
  5. #include "CMain.h"
  6. #include "Forms/CLinkProperties.h"
  7. //------------------------------------------------------------------------------
  8. CMain::CMain(
  9. QWidget *a_parent
  10. ) :
  11. QDialog (a_parent),
  12. #if defined(Q_OS_X11)
  13. _m_hlHAl (a_parent),
  14. #endif
  15. _m_tabLinks (NULL),
  16. _m_dbDatabase (),
  17. _m_smapToolButtons (),
  18. _m_smapLinks (),
  19. _m_tmSystemUsage (),
  20. _m_tmTemperatureUsage(),
  21. _m_tmCurrentDateTime (),
  22. _m_nmNetworkManager (this),
  23. _m_bIsAllowWrap (true),
  24. _m_bIsLinkSwap (false),
  25. _m_btnLinkFrom (NULL),
  26. _m_mnuDirs (),
  27. _m_ptMousePos ()
  28. {
  29. // backup DB
  30. {
  31. CxBackup backup(CxBackup::bpDaily);
  32. try {
  33. std::tstring_t sBackupFilePath;
  34. backup.fileExec(CxPath::exe() + xT(DB_FILE_EXT),
  35. CxPath::exeDir() + CxConst::slash() + xT(BACKUP_DIR_NAME),
  36. &sBackupFilePath);
  37. }
  38. catch (const CxException &e) {
  39. cQString csMsg = QString("CxBackup: ") + qS2QS(e.what());
  40. QMessageBox::warning(this, qApp->applicationName(), csMsg, QMessageBox::Ok);
  41. }
  42. }
  43. _construct();
  44. _settingsLoad();
  45. }
  46. //------------------------------------------------------------------------------
  47. /*******************************************************************************
  48. * CMain
  49. *
  50. *******************************************************************************/
  51. //------------------------------------------------------------------------------
  52. void
  53. CMain::_construct() {
  54. ui.setupUi(this);
  55. //--------------------------------------------------
  56. // settings DB
  57. {
  58. bool bRv = QSqlDatabase::isDriverAvailable("QSQLITE");
  59. qCHECK_DO(false == bRv, qMSG(QSqlDatabase().lastError().text()); return;);
  60. _m_dbDatabase = QSqlDatabase::addDatabase("QSQLITE");
  61. _m_dbDatabase.setDatabaseName(DB_FILE_PATH);
  62. bRv = _m_dbDatabase.open();
  63. qCHECK_REF(bRv, _m_dbDatabase);
  64. {
  65. QSqlQuery qryTable(_m_dbDatabase);
  66. cQString csSql = \
  67. "CREATE TABLE IF NOT EXISTS t_tabs"
  68. "( "
  69. " f_id INTEGER PRIMARY KEY AUTOINCREMENT "
  70. " NOT NULL "
  71. " UNIQUE, "
  72. " f_name VARCHAR(64) NOT NULL "
  73. " UNIQUE "
  74. ")";
  75. bRv = qryTable.exec(csSql);
  76. qCHECK_REF(bRv, qryTable);
  77. }
  78. {
  79. QSqlQuery qryTable(_m_dbDatabase);
  80. cQString csSql = \
  81. "CREATE TABLE IF NOT EXISTS t_main"
  82. "( "
  83. " f_id INTEGER PRIMARY KEY AUTOINCREMENT "
  84. " NOT NULL "
  85. " UNIQUE, "
  86. " f_tab_index INTEGER NOT NULL "
  87. " REFERENCES t_tabs (f_id) "
  88. " ON DELETE RESTRICT "
  89. " ON UPDATE CASCADE, "
  90. " f_link_index INTEGER NOT NULL, "
  91. " f_text VARCHAR(64), "
  92. " f_file_path VARCHAR(255), "
  93. " f_file_params VARCHAR(64) "
  94. ")";
  95. bRv = qryTable.exec(csSql);
  96. qCHECK_REF(bRv, qryTable);
  97. }
  98. }
  99. //--------------------------------------------------
  100. // CMain
  101. {
  102. setWindowTitle(APP_NAME);
  103. // remove window title bar, taskbar
  104. {
  105. Qt::WindowFlags wfFlags = windowFlags();
  106. wfFlags |= Qt::ToolTip;
  107. setWindowFlags(wfFlags);
  108. }
  109. // wrap window
  110. {
  111. cint ciTitleHeight = ui.frTitle->geometry().height();
  112. cint ciTargetHeight = ciTitleHeight;
  113. setFixedHeight(ciTargetHeight);
  114. }
  115. CUtils::widgetAlwaysOnTop(this, true);
  116. }
  117. //--------------------------------------------------
  118. // header
  119. {
  120. // tbtnMenuDirs
  121. _menuDirs_Create(&_m_mnuDirs, ui.tbtnMenuDirs);
  122. ui.tbtnMenuDirs->setPopupMode(QToolButton::InstantPopup);
  123. ui.tbtnMenuDirs->setMenu(&_m_mnuDirs);
  124. ui.tbtnMenuDirs->setIcon(QProxyStyle().standardIcon(QStyle::SP_DirHomeIcon));
  125. #if 0
  126. // tbtnMenuRun
  127. ui.tbtnMenuRun->setPopupMode(QToolButton::InstantPopup);
  128. ui.tbtnMenuRun->setIcon(QProxyStyle().standardIcon(QStyle::SP_CommandLink));
  129. connect(ui.tbtnMenuRun, SIGNAL(pressed()),
  130. this, SLOT (tbtnMenuRun_OnPressed);
  131. #endif
  132. // btnClose
  133. ui.btnClose->setText("");
  134. ui.btnClose->setIcon(QProxyStyle().standardIcon(QStyle::SP_TitleBarCloseButton));
  135. // lblTemperatureUsage
  136. ui.lblTemperatureUsage->setText("<b>T:</b> - ");
  137. // prgCpuUsage, prgMemoryUsage
  138. ui.prgCpuUsage->setFormat("");
  139. ui.prgCpuUsage->setOrientation(Qt::Vertical);
  140. ui.prgCpuUsage->setMaximum(0);
  141. ui.prgCpuUsage->setMaximum(100);
  142. ui.prgCpuUsage->setValue(0);
  143. ui.prgMemoryUsage->setFormat("");
  144. ui.prgMemoryUsage->setOrientation(Qt::Vertical);
  145. ui.prgMemoryUsage->setMaximum(0);
  146. ui.prgMemoryUsage->setMaximum(100);
  147. ui.prgMemoryUsage->setValue(0);
  148. // update usage
  149. systemUsage_OnTimeout();
  150. }
  151. /***************************************************************************
  152. * setup slots
  153. *
  154. ***************************************************************************/
  155. #if defined(Q_OS_X11)
  156. //--------------------------------------------------
  157. // insert/remove device events
  158. {
  159. connect(&_m_hlHAl, &CMain::signal_OnAdded,
  160. this, &CMain::slot_Hal_OnAdded);
  161. connect(&_m_hlHAl, &CMain::signal_OnRemoved,
  162. this, &CMain::slot_Hal_OnRemoved);
  163. }
  164. #endif
  165. //--------------------------------------------------
  166. // signal mappers
  167. {
  168. connect(&_m_smapToolButtons, SIGNAL(mapped(QWidget *)),
  169. this, SLOT (btnVolume_OnClicked(QWidget *)));
  170. connect(&_m_smapLinks, SIGNAL(mapped(QWidget *)),
  171. this, SLOT (btnLink_OnClicked(QWidget *)));
  172. }
  173. //--------------------------------------------------
  174. // "My computer" button
  175. {
  176. ui.tbtnMyComputer->setGeometry( 0 * BUTTON_WIDTH, BUTTON_MARGIN, BUTTON_WIDTH, BUTTON_HEIGHT);
  177. ui.tbtnMyComputer->setAutoRaise(true);
  178. ui.tbtnMyComputer->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
  179. _m_smapToolButtons.setMapping(ui.tbtnMyComputer, ui.tbtnMyComputer);
  180. connect(ui.tbtnMyComputer, &QToolButton::clicked,
  181. this, &CMain::mnuDirs_OnMyComputer);
  182. // ui.tbtnMyComputer->setMenu();
  183. }
  184. //--------------------------------------------------
  185. // volume buttons
  186. {
  187. // fill container
  188. _m_vtbVolumes.push_back(ui.tbtnVolume1);
  189. _m_vtbVolumes.push_back(ui.tbtnVolume2);
  190. _m_vtbVolumes.push_back(ui.tbtnVolume3);
  191. _m_vtbVolumes.push_back(ui.tbtnVolume4);
  192. _m_vtbVolumes.push_back(ui.tbtnVolume5);
  193. _m_vtbVolumes.push_back(ui.tbtnVolume6);
  194. _m_vtbVolumes.push_back(ui.tbtnVolume7);
  195. _m_vtbVolumes.push_back(ui.tbtnVolume8);
  196. // set options
  197. for (int i = 0; i < _m_vtbVolumes.size(); ++ i) {
  198. // start from 2-nd toolbutton
  199. _m_vtbVolumes.at(i)->setGeometry((i + 1) * BUTTON_WIDTH, BUTTON_MARGIN, BUTTON_WIDTH, BUTTON_HEIGHT);
  200. _m_vtbVolumes.at(i)->setAutoRaise(true);
  201. _m_vtbVolumes.at(i)->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
  202. _m_smapToolButtons.setMapping(_m_vtbVolumes.at(i), _m_vtbVolumes.at(i));
  203. connect(_m_vtbVolumes.at(i), SIGNAL(clicked()),
  204. &_m_smapToolButtons, SLOT (map()));
  205. }
  206. _volumes_Rebuild(&_m_vtbVolumes);
  207. }
  208. //--------------------------------------------------
  209. // CMain
  210. {
  211. connect(this, &CMain::signal_title_LClicked,
  212. this, &CMain::title_OnLClicked);
  213. connect(this, &CMain::signal_title_RClicked,
  214. this, &CMain::title_OnRClicked);
  215. ui.frTitle->installEventFilter(this);
  216. connect(&_m_tmSystemUsage, &QTimer::timeout,
  217. this, &CMain::systemUsage_OnTimeout);
  218. // set timeout only for the 1-st launch
  219. _m_tmSystemUsage.start(SYTEM_USAGE_STARTUP_TIMEOUT);
  220. connect(&_m_tmTemperatureUsage, &QTimer::timeout,
  221. this, &CMain::weatherTemp_OnTimeout);
  222. // set timeout only for the 1-st launch
  223. _m_tmTemperatureUsage.start(SYTEM_USAGE_STARTUP_TIMEOUT);
  224. connect(&_m_tmCurrentDateTime, &QTimer::timeout,
  225. this, &CMain::currentDate_OnTimeout);
  226. _m_tmCurrentDateTime.start(CURRENT_DATETIME_TIMEOUT);
  227. connect(&_m_nmNetworkManager, &QNetworkAccessManager::finished,
  228. this, &CMain::networkReply_OnFinished);
  229. connect(ui.btnClose, &QToolButton::clicked,
  230. this, &CMain::btnClose_OnClicked);
  231. }
  232. //--------------------------------------------------
  233. // _m_tabLinks
  234. {
  235. _m_tabLinks = new CTabWidgetEx(this);
  236. xTEST_PTR(_m_tabLinks);
  237. _m_tabLinks->setParent(this);
  238. _m_tabLinks->setMovable(true);
  239. _m_tabLinks->setGeometry(0, TITLEBAR_HEIGHT * 2, TABLINKS_WIDTH, TABLINKS_HEIGHT);
  240. _m_tabLinks->setContextMenuPolicy(Qt::CustomContextMenu);
  241. _m_tabLinks->setCurrentIndex(0); // 0 - first tab
  242. _m_tabLinks->setVisible(true);
  243. connect(_m_tabLinks->tabBarEx(), &QTabBar::tabMoved,
  244. this, &CMain::tabLinks_OnMoved);
  245. connect(_m_tabLinks, SIGNAL(customContextMenuRequested(const QPoint &)),
  246. SLOT (mnuLinks_OnShow(const QPoint &)));
  247. }
  248. //--------------------------------------------------
  249. // create tab pages
  250. {
  251. // from DB
  252. QSqlQuery qryTabs(_m_dbDatabase);
  253. cQString csSql = \
  254. "SELECT f_name FROM t_tabs";
  255. bool bRv = qryTabs.exec(csSql);
  256. qCHECK_REF(bRv, qryTabs);
  257. // create
  258. for ( ; true == qryTabs.next(); ) {
  259. cQString csTabName = qryTabs.value(0).toString(); // 0 - f_name
  260. _tabPageShow(csTabName);
  261. }
  262. }
  263. //--------------------------------------------------
  264. // statusbar
  265. {
  266. // font
  267. {
  268. QFont fntFont( ui.lblDayOfWeek->font() );
  269. fntFont.setPointSize( ui.lblDayOfWeek->font().pointSize() );
  270. fntFont.setBold(false);
  271. ui.lblDayOfWeek->setFont(fntFont);
  272. }
  273. // ui.lblDayOfWeek->setAlignment(Qt::AlignCenter);
  274. currentDate_OnTimeout();
  275. }
  276. }
  277. //------------------------------------------------------------------------------
  278. void
  279. CMain::_destruct() {
  280. _settingsSave();
  281. }
  282. //------------------------------------------------------------------------------
  283. void
  284. CMain::title_OnLClicked() {
  285. int iTitleHeight = 0;
  286. int iTargetHeight = 0;
  287. if (TITLEBAR_HEIGHT == height()) {
  288. // unwrap main window
  289. iTitleHeight = ui.frTitle->geometry().height();
  290. iTargetHeight = iTitleHeight + TITLEBAR_HEIGHT + _m_tabLinks->height();
  291. } else {
  292. // wrap main window
  293. qCHECK_DO(false == _m_bIsAllowWrap, return);
  294. iTitleHeight = ui.frTitle->geometry().height();
  295. iTargetHeight = iTitleHeight;
  296. }
  297. setFixedWidth(width());
  298. setFixedHeight(iTargetHeight);
  299. }
  300. //------------------------------------------------------------------------------
  301. void
  302. CMain::title_OnRClicked() {
  303. static bool s_bFlagIsMinimize = false;
  304. s_bFlagIsMinimize = !s_bFlagIsMinimize;
  305. // TODO: CUtils::desktopWindowsMinimize(s_bFlagIsMinimize);
  306. }
  307. //------------------------------------------------------------------------------
  308. void
  309. CMain::tbtnMenuRun_OnPressed() {
  310. // wrap window
  311. {
  312. cint iTitleHeight = ui.frTitle->geometry().height();
  313. cint iTargetHeight = iTitleHeight;
  314. setFixedHeight(iTargetHeight);
  315. }
  316. QClipboard *pcbClipboard = QApplication::clipboard();
  317. xTEST_PTR(pcbClipboard);
  318. cQString csProgram = pcbClipboard->text().trimmed();
  319. cQString cslArgs; // TODO: cslArgs
  320. qCHECK_DO(true == csProgram.isEmpty(), return);
  321. QString sDir = QString("file:///%1")
  322. .arg(csProgram);
  323. bool bRv = QDesktopServices::openUrl( QUrl(sDir) );
  324. xTEST_EQ(true, bRv);
  325. }
  326. //------------------------------------------------------------------------------
  327. /*******************************************************************************
  328. * protected
  329. *
  330. *******************************************************************************/
  331. //------------------------------------------------------------------------------
  332. /*virtual*/
  333. bool
  334. CMain::eventFilter(
  335. QObject *a_object,
  336. QEvent *a_event
  337. )
  338. {
  339. // title clicks
  340. if (ui.frTitle == a_object) {
  341. if (QEvent::MouseButtonPress == a_event->type()) {
  342. QMouseEvent *mouseEvent = static_cast<QMouseEvent *>( a_event );
  343. if (Qt::LeftButton == mouseEvent->button()) {
  344. emit signal_title_LClicked();
  345. }
  346. else if (Qt::RightButton == mouseEvent->button()) {
  347. emit signal_title_RClicked();
  348. }
  349. else {
  350. xNA;
  351. }
  352. }
  353. }
  354. return false;
  355. }
  356. //------------------------------------------------------------------------------
  357. /*virtual*/
  358. void
  359. CMain::focusInEvent(
  360. QFocusEvent *a_event
  361. )
  362. {
  363. if (true == a_event->gotFocus()) {
  364. _volumes_Rebuild(&_m_vtbVolumes);
  365. }
  366. QWidget::focusInEvent(a_event);
  367. }
  368. //------------------------------------------------------------------------------
  369. /*virtual*/
  370. void
  371. CMain::focusOutEvent(
  372. QFocusEvent *a_event
  373. )
  374. {
  375. if (true == a_event->lostFocus()) {
  376. if (TITLEBAR_HEIGHT < height()) {
  377. title_OnLClicked();
  378. }
  379. }
  380. QWidget::focusOutEvent(a_event);
  381. }
  382. //------------------------------------------------------------------------------
  383. /* virtual */
  384. void
  385. CMain::closeEvent(
  386. QCloseEvent *a_event
  387. )
  388. {
  389. _destruct();
  390. a_event->accept();
  391. }
  392. //------------------------------------------------------------------------------
  393. /*******************************************************************************
  394. * header - insert / remove device events
  395. *
  396. *******************************************************************************/
  397. //------------------------------------------------------------------------------
  398. #if defined(Q_OS_WIN)
  399. /* virtual */
  400. bool
  401. CMain::nativeEvent(
  402. cQByteArray &a_eventType,
  403. void *a_message,
  404. long *a_result
  405. )
  406. {
  407. /*
  408. * Platform Event Type Identifier Message Type Result Type
  409. * Windows "windows_generic_MSG" MSG * LRESULT
  410. */
  411. MSG *pmsgMsg = static_cast<MSG *>(a_message);
  412. Q_UNUSED(a_result);
  413. xCHECK_RET(NULL == pmsgMsg, false);
  414. // inserting volume
  415. if (WM_DEVICECHANGE == pmsgMsg->message &&
  416. DBT_DEVICEARRIVAL == pmsgMsg->wParam
  417. )
  418. {
  419. _volumes_Rebuild(&_m_vtbVolumes);
  420. return true;
  421. }
  422. // removing volume
  423. if (WM_DEVICECHANGE == pmsgMsg->message &&
  424. DBT_DEVICEREMOVECOMPLETE == pmsgMsg->wParam
  425. )
  426. {
  427. _volumes_Rebuild(&_m_vtbVolumes);
  428. return true;
  429. }
  430. return QWidget::nativeEvent(a_eventType, a_message, a_result);
  431. }
  432. #elif defined(Q_OS_X11)
  433. //------------------------------------------------------------------------------
  434. // HAL
  435. void
  436. CMain::slot_Hal_OnAdded(cQString &dev) {
  437. qDebug() << __FUNCTION__ << dev;
  438. _volumes_Rebuild(&_m_vtbVolumes);
  439. }
  440. //------------------------------------------------------------------------------
  441. void
  442. CMain::slot_Hal_OnRemoved(cQString &dev) {
  443. qDebug() << __FUNCTION__ << dev;
  444. _volumes_Rebuild(&_m_vtbVolumes);
  445. }
  446. //------------------------------------------------------------------------------
  447. #endif // Q_OS_X11
  448. /*******************************************************************************
  449. * header - GUI
  450. *
  451. *******************************************************************************/
  452. //------------------------------------------------------------------------------
  453. void
  454. CMain::systemUsage_OnTimeout() {
  455. CxSystemInfo info;
  456. const ulong_t culCpuUsage = info.cpuUsage();
  457. const ulong_t culRamUsage = info.ramUsage();
  458. cQString csCpuUsage = QString("<b>CPU:</b> %1%").arg(culCpuUsage);
  459. cQString csMemoryUsage = QString("<b>RAM:</b> %1%").arg(culRamUsage);
  460. // prgCpuUsage
  461. ui.prgCpuUsage->setValue(culCpuUsage);
  462. ui.prgCpuUsage->setToolTip(csCpuUsage);
  463. // prgMemoryUsage
  464. ui.prgMemoryUsage->setValue(culRamUsage);
  465. ui.prgMemoryUsage->setToolTip(csMemoryUsage);
  466. }
  467. //------------------------------------------------------------------------------
  468. void
  469. CMain::weatherTemp_OnTimeout() {
  470. _m_tmTemperatureUsage.setInterval(WEATHER_TEMPR_CHECK_TIMEOUT);
  471. #if 0
  472. /**
  473. * Google API
  474. *
  475. * FAQ:
  476. * HTTP GET: http://www.google.com/ig/api?weather=kiev&hl=en
  477. */
  478. QUrl urUrl("http://www.google.com/ig/api");
  479. urUrl.addEncodedQueryItem("weather", QUrl::toPercentEncoding(WEATHER_TEMPR_CITY));
  480. urUrl.addEncodedQueryItem("hl", "en");
  481. #endif
  482. /**
  483. * Yahoo API
  484. *
  485. * FAQ: http://developer.yahoo.com/weather/
  486. * HTTP GET: http://weather.yahooapis.com/forecastrss?w=924938&u=c
  487. */
  488. QUrl urUrl("http://weather.yahooapis.com/forecastrss?w=924938&u=c");
  489. urUrl.toEncoded();
  490. QNetworkRequest nrRequest;
  491. nrRequest.setUrl(urUrl);
  492. #if 1
  493. _m_nmNetworkManager.get(nrRequest);
  494. #endif
  495. }
  496. //------------------------------------------------------------------------------
  497. void
  498. CMain::currentDate_OnTimeout() {
  499. cQString csDate = QDate().currentDate().toString("dd.MM.yyyy");
  500. cQString csDayOfWeek = QDate().currentDate().toString("ddd");
  501. cQString csTime = QTime().currentTime().toString("H:mm");
  502. cQString csDateTimeFormated = QString("<b>%1</b> <u>%2</u> %3")
  503. .arg(csTime)
  504. .arg(csDayOfWeek)
  505. .arg(csDate);
  506. ui.lblDayOfWeek->setText(csDateTimeFormated);
  507. }
  508. //------------------------------------------------------------------------------
  509. void
  510. CMain::networkReply_OnFinished(
  511. QNetworkReply *a_pnrReply
  512. )
  513. {
  514. QString sRv;
  515. cint ciStatus = a_pnrReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
  516. if (200 == ciStatus) {
  517. cQString csText = QString::fromUtf8(a_pnrReply->readAll());
  518. sRv = QString("<b>T:</b> %1").arg( _yahooReplyParse(csText) );
  519. } else {
  520. qDebug() << "ciStatus: " << ciStatus;
  521. sRv = QString("<b>T:</b> %1").arg("-");
  522. }
  523. ui.lblTemperatureUsage->setText(sRv);
  524. a_pnrReply->deleteLater();
  525. }
  526. //------------------------------------------------------------------------------
  527. QString
  528. CMain::_googleReplyParse(
  529. cQString &a_csXml
  530. )
  531. {
  532. QXmlStreamReader xml(a_csXml);
  533. while (!xml.atEnd()) {
  534. xml.readNext();
  535. qCHECK_DO(QXmlStreamReader::StartElement != xml.tokenType(), continue);
  536. // Parse current weather conditions
  537. if (xml.name() == "current_conditions") {
  538. while (!xml.atEnd()) {
  539. xml.readNext();
  540. if ("current_conditions" == xml.name()) {
  541. break;
  542. }
  543. if (QXmlStreamReader::StartElement == xml.tokenType()) {
  544. if ("temp_c" == xml.name()) {
  545. QString sTempr = xml.attributes().value("data").toString().trimmed();
  546. xCHECK_RET(true == sTempr.isEmpty(), "-");
  547. // add "+" prefix to temperature
  548. if ("-" == sTempr.at(0)) {
  549. xNA;
  550. } else {
  551. sTempr = "+" + sTempr;
  552. }
  553. return QString("%1%2%3")
  554. .arg(sTempr)
  555. .arg(QChar(176))
  556. .arg("C");
  557. }
  558. }
  559. }
  560. }
  561. }
  562. return "-";
  563. }
  564. //------------------------------------------------------------------------------
  565. QString
  566. CMain::_yahooReplyParse(
  567. cQString &a_csXml
  568. )
  569. {
  570. QXmlStreamReader xml(a_csXml);
  571. while (!xml.atEnd()) {
  572. xml.readNext();
  573. qCHECK_DO(QXmlStreamReader::StartElement != xml.tokenType(), continue);
  574. // parse:
  575. // <yweather:condition text="Light Rain Shower" code="11" temp="5"
  576. // date="Thu, 11 Oct 2012 9:58 am EEST" />
  577. if (xml.name() == "condition") {
  578. QString sTempr = xml.attributes().value("temp").toString().trimmed();
  579. qCHECK_RET(true == sTempr.isEmpty(), "-");
  580. // add "+" prefix to temperature
  581. if ("-" == sTempr.at(0)) {
  582. xNA;
  583. } else {
  584. sTempr = "+" + sTempr;
  585. }
  586. return QString("%1%2%3")
  587. .arg(sTempr)
  588. .arg(QChar(176))
  589. .arg("C");
  590. }
  591. }
  592. return "-";
  593. }
  594. //------------------------------------------------------------------------------
  595. void
  596. CMain::_settingsLoad() {
  597. QSize szSize;
  598. QPoint pnPosition;
  599. {
  600. QSettings stSettings(INI_FILE_PATH, QSettings::IniFormat, this);
  601. stSettings.beginGroup("main");
  602. szSize = stSettings.value("size", APP_SIZE).toSize();
  603. pnPosition = stSettings.value("position", QPoint(200, 200)).toPoint();
  604. stSettings.endGroup();
  605. }
  606. // apply settings
  607. {
  608. resize(szSize);
  609. move(pnPosition);
  610. }
  611. }
  612. //------------------------------------------------------------------------------
  613. void
  614. CMain::_settingsSave() {
  615. QSettings stSettings(INI_FILE_PATH, QSettings::IniFormat, this);
  616. stSettings.beginGroup("main");
  617. stSettings.setValue("position", pos());
  618. stSettings.setValue("size", size());
  619. stSettings.endGroup();
  620. }
  621. //------------------------------------------------------------------------------
  622. void
  623. CMain::btnClose_OnClicked() {
  624. close();
  625. }
  626. //------------------------------------------------------------------------------
  627. /*******************************************************************************
  628. * CLinkButton
  629. *
  630. *******************************************************************************/
  631. //------------------------------------------------------------------------------
  632. void
  633. CMain::_tabPageAddEmpty(
  634. cQString &a_tabName
  635. )
  636. {
  637. // to DB (t_tabs)
  638. {
  639. QSqlQuery qryInsert(_m_dbDatabase);
  640. cQString csSql = \
  641. "INSERT INTO t_tabs (f_name) VALUES (:p_tab_name)";
  642. bool bRv = qryInsert.prepare(csSql);
  643. qCHECK_REF(bRv, qryInsert)
  644. qryInsert.bindValue(":p_tab_name", a_tabName);
  645. bRv = qryInsert.exec();
  646. qCHECK_REF(bRv, qryInsert);
  647. }
  648. // DB (t_main)
  649. {
  650. cint _ciTabIndex = _m_tabLinks->count();
  651. for (int x = 0, index = 0; x < TAB_X; ++ x) {
  652. for (int y = 0; y < TAB_Y; ++ y, ++ index) {
  653. cint ciTabIndex = _ciTabIndex;
  654. cint ciLinkIndex = index;
  655. cQString csText;
  656. cQString csFilePath;
  657. cQString csFileParams;
  658. QSqlQuery qryInsert(_m_dbDatabase);
  659. cQString csSql = \
  660. "INSERT INTO "
  661. " t_main (f_tab_index, f_link_index, f_text, f_file_path, f_file_params) "
  662. "VALUES "
  663. " (:p_tab_index, :p_link_index, :p_text, :p_file_path, :p_file_params)";
  664. bool bRv = qryInsert.prepare(csSql);
  665. qCHECK_REF(bRv, qryInsert)
  666. qryInsert.bindValue(":p_tab_index", ciTabIndex);
  667. qryInsert.bindValue(":p_link_index", ciLinkIndex);
  668. qryInsert.bindValue(":p_text", csText);
  669. qryInsert.bindValue(":p_file_path", csFilePath);
  670. qryInsert.bindValue(":p_file_params", csFileParams);
  671. bRv = qryInsert.exec();
  672. qCHECK_REF(bRv, qryInsert);
  673. }
  674. }
  675. }
  676. }
  677. //------------------------------------------------------------------------------
  678. void
  679. CMain::_tabPageShow(
  680. cQString &a_tabName
  681. )
  682. {
  683. cint _ciTabIndex = _m_tabLinks->addTab(new QWidget(), a_tabName);
  684. // build current tab (4x10)
  685. for (int x = 0, index = 0; x < TAB_X; ++ x) {
  686. for (int y = 0; y < TAB_Y; ++ y, ++ index) {
  687. cint ciTabIndex = _ciTabIndex;
  688. cint ciLinkIndex = index;
  689. QString sText;
  690. QString sFilePath;
  691. QString sFileParams;
  692. // DB (get link data from DB)
  693. {
  694. QSqlQuery qryLinks(_m_dbDatabase);
  695. cQString csSql = \
  696. "SELECT f_text, f_file_path, f_file_params "
  697. " FROM t_main "
  698. "WHERE "
  699. " (f_tab_index=:p_tab_index AND f_link_index=:p_link_index)";
  700. bool bRv = qryLinks.prepare(csSql);
  701. qCHECK_REF(bRv, qryLinks)
  702. qryLinks.bindValue(":p_tab_index", ciTabIndex);
  703. qryLinks.bindValue(":p_link_index", ciLinkIndex);
  704. bRv = qryLinks.exec();
  705. qCHECK_REF(bRv, qryLinks);
  706. // assignment
  707. if (true == qryLinks.next()) {
  708. sText = qryLinks.value(0).toString(); /* 0 - f_text */
  709. sFilePath = qryLinks.value(1).toString(); /* 1 - f_file_path */
  710. sFileParams = qryLinks.value(2).toString(); /* 2 - f_file_params */
  711. } else {
  712. sText.clear();
  713. sFilePath.clear();
  714. sFileParams.clear();
  715. }
  716. }
  717. // Ui
  718. {
  719. // create link
  720. CLinkButton *pbtnLink = new CLinkButton;
  721. xTEST_PTR(pbtnLink);
  722. pbtnLink->setGeometry(x * SHORTCUT_WIDTH, y * SHORTCUT_HEIGHT, SHORTCUT_WIDTH, SHORTCUT_HEIGHT);
  723. _linkUpdate(pbtnLink, ciTabIndex, ciLinkIndex, sText, sFilePath, sFileParams);
  724. // context menu
  725. pbtnLink->setContextMenuPolicy(Qt::CustomContextMenu);
  726. connect(pbtnLink, SIGNAL(customContextMenuRequested(const QPoint &)),
  727. SLOT (mnuLink_OnShow(const QPoint &)));
  728. // clicked()
  729. _m_smapLinks.setMapping(pbtnLink, pbtnLink);
  730. connect(pbtnLink, SIGNAL(clicked()),
  731. &_m_smapLinks, SLOT(map()));
  732. }
  733. }
  734. }
  735. }
  736. //------------------------------------------------------------------------------
  737. void
  738. CMain::_linkUpdate(
  739. CLinkButton *a_pbtnLink,
  740. cint &a_tabIndex,
  741. cint &a_linkIndex,
  742. cQString &a_text,
  743. cQString &a_filePath,
  744. cQString &a_fileParams
  745. )
  746. {
  747. xTEST_PTR(a_pbtnLink);
  748. xTEST_LESS(- 1, a_tabIndex);
  749. xTEST_LESS(- 1, a_linkIndex);
  750. // a_filePath - n/a
  751. // a_fileParams - n/a
  752. a_pbtnLink->setParent( _m_tabLinks->widget(a_tabIndex) );
  753. a_pbtnLink->setAutoRaise(true);
  754. a_pbtnLink->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
  755. a_pbtnLink->setVisible(true);
  756. a_pbtnLink->setTabIndex(a_tabIndex);
  757. a_pbtnLink->setLinkIndex(a_linkIndex);
  758. // icon
  759. {
  760. QIcon icoIcon;
  761. if (true == a_filePath.isEmpty()) {
  762. xNA;
  763. } else {
  764. QFileInfo fiInfo(a_filePath);
  765. icoIcon = QFileIconProvider().icon(fiInfo);
  766. }
  767. a_pbtnLink->setIconSize(BUTTON_ICON_SIZE);
  768. a_pbtnLink->setIcon(icoIcon);
  769. }
  770. a_pbtnLink->setText(a_text);
  771. a_pbtnLink->setToolTip(a_filePath);
  772. a_pbtnLink->setFilePath(a_filePath);
  773. a_pbtnLink->setFileParams(a_fileParams);
  774. }
  775. //------------------------------------------------------------------------------
  776. /*******************************************************************************
  777. * _m_vtbVolumes
  778. *
  779. *******************************************************************************/
  780. //------------------------------------------------------------------------------
  781. void
  782. CMain::btnVolume_OnClicked(
  783. QWidget *a_ptbtnVolume
  784. )
  785. {
  786. // wrap window
  787. {
  788. cint ciTitleHeight = ui.frTitle->geometry().height();
  789. cint ciTargetHeight = ciTitleHeight;
  790. setFixedHeight(ciTargetHeight);
  791. }
  792. QToolButton *ptbTB = dynamic_cast<QToolButton *>( a_ptbtnVolume );
  793. xTEST_PTR(ptbTB);
  794. #if defined(Q_OS_WIN)
  795. cQString sVolumePath = ptbTB->text() + ":";
  796. #else
  797. cQString sVolumePath = ptbTB->text();
  798. #endif
  799. qCHECK_DO(!CxVolume( qQS2S(sVolumePath) ).isReady(), return);
  800. bool bRv = QDesktopServices::openUrl( QString("file:///%1").arg(sVolumePath) );
  801. xTEST_EQ(true, bRv);
  802. }
  803. //------------------------------------------------------------------------------
  804. bool
  805. CMain::_volumes_Rebuild(
  806. volume_buttons_t *a_pvtbVolumes
  807. )
  808. {
  809. xTEST_PTR(a_pvtbVolumes);
  810. //--------------------------------------------------
  811. // "My computer" button
  812. {
  813. // icon
  814. {
  815. QIcon icoVolume = QFileIconProvider().icon( QFileIconProvider::Computer );
  816. ui.tbtnMyComputer->setIcon(icoVolume);
  817. }
  818. // tooltip
  819. {
  820. CxSystemInfo info;
  821. std::tstring_t sToolTip = CxString::format(
  822. xT("OS: %s (%s)\n")
  823. xT("Shell: %s\n")
  824. xT("Host: %s\n")
  825. xT("User: %s\n")
  826. xT("Cpu: %s %ld MHz\n")
  827. xT("Ram: %s"),
  828. info.formatOsType().c_str(),
  829. info.formatOsArch().c_str(),
  830. info.desktopName().c_str(),
  831. info.hostName().c_str(),
  832. info.userName().c_str(),
  833. info.cpuModel().c_str(),
  834. info.cpuSpeed(),
  835. CxString::formatBytes( info.ramTotal() ).c_str()
  836. );
  837. ui.tbtnMyComputer->setToolTip( qS2QS(sToolTip) );
  838. }
  839. }
  840. //--------------------------------------------------
  841. // hide volume buttons
  842. for (int i = 0; i < a_pvtbVolumes->size(); ++ i) {
  843. a_pvtbVolumes->at(i)->setVisible(false);
  844. }
  845. //--------------------------------------------------
  846. // build volume buttons
  847. std::vector<std::tstring_t> vsVolumes;
  848. CxVolume::paths(&vsVolumes);
  849. // HACK: when mobile (SE) inserted - QVector<T>::at: "index out of range"
  850. {
  851. std::csize_t ciVolumesMax = 8;
  852. if (ciVolumesMax < vsVolumes.size()) {
  853. vsVolumes.resize(ciVolumesMax);
  854. }
  855. }
  856. for (size_t i = 0; i < vsVolumes.size(); ++ i) {
  857. // text
  858. {
  859. std::tstring_t sCaption = vsVolumes.at(i);
  860. #if defined(Q_OS_WIN)
  861. // remove colon and slash
  862. sCaption.resize(vsVolumes.at(i).size() - std::tstring_t(xT(":\\")).size());
  863. #endif
  864. a_pvtbVolumes->at(i)->setText( qS2QS(sCaption) );
  865. }
  866. // icon
  867. {
  868. QFileIconProvider fipProvider;
  869. QFileInfo fiInfo( qS2QS(vsVolumes.at(i)) );
  870. QIcon icoVolume = fipProvider.icon(fiInfo);
  871. a_pvtbVolumes->at(i)->setIcon(icoVolume);
  872. }
  873. // tooltip
  874. {
  875. std::tstring_t sLabel;
  876. ulonglong_t ullFreeBytesAvailable = 0ULL;
  877. ulonglong_t ullTotalNumberOfBytes = 0ULL;
  878. ulonglong_t ullTotalNumberOfFreeBytes = 0ULL;
  879. bool bRv = CxVolume(vsVolumes.at(i)).isReady();
  880. if (false == bRv) {
  881. sLabel = xT("");
  882. ullFreeBytesAvailable = 0ULL;
  883. ullTotalNumberOfBytes = 0ULL;
  884. ullTotalNumberOfFreeBytes = 0ULL;
  885. } else {
  886. sLabel = CxVolume(vsVolumes.at(i)).label();
  887. CxVolume::space(vsVolumes.at(i),
  888. &ullFreeBytesAvailable,
  889. &ullTotalNumberOfBytes,
  890. &ullTotalNumberOfFreeBytes);
  891. }
  892. std::tstring_t sToolTip = CxString::format(
  893. xT("Label: %s\n")
  894. xT("Total: %s\n")
  895. xT("Free: %s"),
  896. sLabel.c_str(),
  897. CxString::formatBytes(ullTotalNumberOfBytes).c_str(),
  898. CxString::formatBytes(ullTotalNumberOfFreeBytes).c_str()
  899. );
  900. a_pvtbVolumes->at(i)->setToolTip( qS2QS(sToolTip) );
  901. }
  902. // visible
  903. {
  904. a_pvtbVolumes->at(i)->setVisible(true);
  905. }
  906. }
  907. return true;
  908. }
  909. //------------------------------------------------------------------------------
  910. /*******************************************************************************
  911. * menu Dirs
  912. *
  913. *******************************************************************************/
  914. //------------------------------------------------------------------------------
  915. void
  916. CMain::_menuDirs_Create(
  917. QMenu *a_pmnuMenu,
  918. QObject *a_parent
  919. )
  920. {
  921. QString sControlPanelPath;
  922. // get "control.exe" file path (for getting icon)
  923. {
  924. #if defined(Q_OS_WIN)
  925. std::tstring_t sRv;
  926. sRv.resize(xPATH_MAX);
  927. UINT uiRes = ::GetSystemDirectory(&sRv.at(0), sRv.size());
  928. sRv.resize(uiRes);
  929. sRv += CxConst::xSLASH;
  930. sRv += xT("control.exe");
  931. sControlPanelPath = qS2QS(sRv);
  932. #else
  933. #pragma message "TODO: get 'control.exe' file path (for getting icon)"
  934. #endif
  935. }
  936. // get "My documents" dir path (for getting icon)
  937. QString sMyDocumentsPath;
  938. sMyDocumentsPath = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
  939. // icons
  940. QIcon icoHome = QProxyStyle().standardIcon(QStyle::SP_DirHomeIcon);
  941. QIcon icoDesktop = QFileIconProvider().icon( QFileIconProvider::Desktop );
  942. QIcon icoProgramFiles = QFileIconProvider().icon( QFileIconProvider::Folder );
  943. QIcon icoMyDocuments = QFileIconProvider().icon( QFileInfo(sMyDocumentsPath) );
  944. QIcon icoMyComputer = QFileIconProvider().icon( QFileIconProvider::Computer );
  945. QIcon icoControlPanel = QFileIconProvider().icon( QFileInfo(sControlPanelPath) );
  946. QIcon icoOsCore = QFileIconProvider().icon( QFileIconProvider::Folder );
  947. #if defined(Q_OS_WIN)
  948. QIcon icoAutorun = QFileIconProvider().icon( QFileIconProvider::Folder );
  949. QIcon icoSendTo = QFileIconProvider().icon( QFileIconProvider::Folder );
  950. #endif
  951. QIcon icoTemp = QFileIconProvider().icon( QFileIconProvider::Folder );
  952. QIcon icoNetwork = QFileIconProvider().icon( QFileIconProvider::Network );
  953. QIcon icoTrash = QFileIconProvider().icon( QFileIconProvider::Trashcan );
  954. // actions
  955. QAction *acHome = new QAction(icoHome, tr("Home"), a_parent);
  956. connect(acHome, &QAction::triggered,
  957. this, &CMain::mnuDirs_OnHome);
  958. QAction *acDesktop = new QAction(icoDesktop, tr("Desktop"), a_parent);
  959. connect(acDesktop, &QAction::triggered,
  960. this, &CMain::mnuDirs_OnDesktop);
  961. QAction *acProgramFiles = new QAction(icoProgramFiles, tr("Program files"), a_parent);
  962. connect(acProgramFiles, &QAction::triggered,
  963. this, &CMain::mnuDirs_OnProgramFiles);
  964. QAction *acMyDocuments = new QAction(icoMyDocuments, tr("My documents"), a_parent);
  965. connect(acMyDocuments, &QAction::triggered,
  966. this, &CMain::mnuDirs_OnMyDocuments);
  967. QAction *acMyComputer = new QAction(icoMyComputer, tr("My computer"), a_parent);
  968. connect(acMyComputer, &QAction::triggered,
  969. this, &CMain::mnuDirs_OnMyComputer);
  970. QAction *acControlPanel = new QAction(icoControlPanel, tr("Control panel"), a_parent);
  971. connect(acControlPanel, &QAction::triggered,
  972. this, &CMain::mnuDirs_OnControlPanel);
  973. QAction *acOsCore = new QAction(icoOsCore, tr("OS core"), a_parent);
  974. connect(acOsCore, &QAction::triggered,
  975. this, &CMain::mnuDirs_OnOsCore);
  976. #if defined(Q_OS_WIN)
  977. QAction *acAutorun = new QAction(icoAutorun, tr("Autorun"), a_parent);
  978. connect(acAutorun, &QAction::triggered,
  979. this, &CMain::mnuDirs_OnAutorun);
  980. QAction *acSendTo = new QAction(icoSendTo, tr("Sent to"), a_parent);
  981. connect(acSendTo, &QAction::triggered,
  982. this, &CMain::mnuDirs_OnSendTo);
  983. #endif
  984. QAction *acTemp = new QAction(icoTemp, tr("Temp"), a_parent);
  985. connect(acTemp, &QAction::triggered,
  986. this, &CMain::mnuDirs_OnTemp);
  987. QAction *acNetwork = new QAction(icoNetwork, tr("Network"), a_parent);
  988. connect(acNetwork, &QAction::triggered,
  989. this, &CMain::mnuDirs_OnNetwork);
  990. QAction *acTrash = new QAction(icoTrash, tr("Trash"), a_parent);
  991. connect(acTrash, &QAction::triggered,
  992. this, &CMain::mnuDirs_OnTrash);
  993. // add actions
  994. a_pmnuMenu->addAction(acHome);
  995. a_pmnuMenu->addAction(acDesktop);
  996. a_pmnuMenu->addAction(acProgramFiles);
  997. a_pmnuMenu->addAction(acMyDocuments);
  998. a_pmnuMenu->addAction(acMyComputer);
  999. a_pmnuMenu->addAction(acControlPanel);
  1000. a_pmnuMenu->addAction(acOsCore);
  1001. #if defined(Q_OS_WIN)
  1002. a_pmnuMenu->addAction(acAutorun);
  1003. a_pmnuMenu->addAction(acSendTo);
  1004. #endif
  1005. a_pmnuMenu->addAction(acTemp);
  1006. a_pmnuMenu->addAction(acNetwork);
  1007. a_pmnuMenu->addAction(acTrash);
  1008. }
  1009. //------------------------------------------------------------------------------
  1010. void
  1011. CMain::mnuDirs_OnHome() {
  1012. cQString csDir = QString("file:///%1")
  1013. .arg(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
  1014. bool bRv = QDesktopServices::openUrl(csDir);
  1015. xTEST_EQ(true, bRv);
  1016. }
  1017. //------------------------------------------------------------------------------
  1018. void
  1019. CMain::mnuDirs_OnDesktop() {
  1020. cQString csDir = QString("file:///%1")
  1021. .arg(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation));
  1022. bool bRv = QDesktopServices::openUrl(csDir);
  1023. xTEST_EQ(true, bRv);
  1024. }
  1025. //------------------------------------------------------------------------------
  1026. void
  1027. CMain::mnuDirs_OnProgramFiles() {
  1028. QString sDir;
  1029. {
  1030. #if defined(Q_OS_WIN)
  1031. LPITEMIDLIST pidl = {0};
  1032. ::SHGetSpecialFolderLocation(NULL, CSIDL_PROGRAM_FILES , &pidl);
  1033. tchar_t szBuff[MAX_PATH + 1] = {0};
  1034. ::SHGetPathFromIDList(pidl, szBuff);
  1035. sDir = QString("file:///") + qS2QS(szBuff);
  1036. #else
  1037. sDir = QString("file:///%1").arg(SPECIAL_DIR_PROGRAM_FILES);
  1038. #endif
  1039. }
  1040. bool bRv = QDesktopServices::openUrl( QUrl(sDir) );
  1041. xTEST_EQ(true, bRv);
  1042. }
  1043. //------------------------------------------------------------------------------
  1044. void
  1045. CMain::mnuDirs_OnMyDocuments() {
  1046. cQString csDir = QString("file:///%1")
  1047. .arg(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
  1048. bool bRv = QDesktopServices::openUrl(csDir);
  1049. xTEST_EQ(true, bRv);
  1050. }
  1051. //------------------------------------------------------------------------------
  1052. void
  1053. CMain::mnuDirs_OnMyComputer() {
  1054. #if defined(Q_OS_WIN)
  1055. LPITEMIDLIST lst = {0};
  1056. SHELLEXECUTEINFO se = {0};
  1057. ::SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &lst);
  1058. se.cbSize = sizeof(se);
  1059. se.fMask = SEE_MASK_IDLIST;
  1060. se.hwnd = NULL;
  1061. se.lpVerb = xT("open");
  1062. se.nShow = SW_SHOW;
  1063. se.lpIDList = lst;
  1064. ::ShellExecuteEx(&se);
  1065. (void)::CoTaskMemFree(lst);
  1066. #else
  1067. cQString csDir = QString("file:///%1").arg(QDir::rootPath());
  1068. bool bRv = QDesktopServices::openUrl( QUrl(csDir) );
  1069. xTEST_EQ(true, bRv);
  1070. #endif
  1071. }
  1072. //------------------------------------------------------------------------------
  1073. void
  1074. CMain::mnuDirs_OnControlPanel() {
  1075. #if defined(Q_OS_WIN)
  1076. LPITEMIDLIST lst = {0};
  1077. SHELLEXECUTEINFO se = {0};
  1078. ::SHGetSpecialFolderLocation(NULL, CSIDL_CONTROLS, &lst);
  1079. se.cbSize = sizeof(se);
  1080. se.fMask = SEE_MASK_IDLIST;
  1081. se.hwnd = NULL;
  1082. se.lpVerb = xT("open");
  1083. se.nShow = SW_SHOW;
  1084. se.lpIDList = lst;
  1085. ::ShellExecuteEx(&se);
  1086. (void)::CoTaskMemFree(lst);
  1087. #else
  1088. QString sFile;
  1089. cQString csDesktop = QString().fromStdString( CxSystemInfo().desktopName() );
  1090. if ("gnome" == csDesktop) {
  1091. sFile = "/usr/bin/gnome-control-center";
  1092. }
  1093. else if ("kde" == csDesktop || "kde-plasma" == csDesktop) {
  1094. sFile = "/usr/bin/systemsettings";
  1095. }
  1096. else if ("xfce" == csDesktop) {
  1097. sFile = "/usr/bin/xfce4-settings-manager";
  1098. }
  1099. else {
  1100. sFile = "";
  1101. }
  1102. qDebug() << qDEBUG_VAR(csDesktop);
  1103. cQString dir = QString("file:///%1").arg(sFile);
  1104. bool bRv = QDesktopServices::openUrl( QUrl(dir) );
  1105. xTEST_EQ(true, bRv);
  1106. #endif
  1107. }
  1108. //------------------------------------------------------------------------------
  1109. void
  1110. CMain::mnuDirs_OnOsCore() {
  1111. QString sDir;
  1112. {
  1113. #if defined(Q_OS_WIN)
  1114. LPITEMIDLIST pidl = {0};
  1115. ::SHGetSpecialFolderLocation(NULL, CSIDL_WINDOWS, &pidl);
  1116. tchar_t szBuff[MAX_PATH + 1] = {0};
  1117. ::SHGetPathFromIDList(pidl, szBuff);
  1118. sDir = QString("file:///%1") + qS2QS(szBuff);
  1119. #else
  1120. sDir = QString("file:///%1").arg(SPECIAL_DIR_OS_CORE);
  1121. #endif
  1122. }
  1123. bool bRv = QDesktopServices::openUrl( QUrl(sDir) );
  1124. xTEST_EQ(true, bRv);
  1125. }
  1126. //------------------------------------------------------------------------------
  1127. #if defined(Q_OS_WIN)
  1128. void
  1129. CMain::mnuDirs_OnAutorun() {
  1130. QString sDir;
  1131. {
  1132. #if defined(Q_OS_WIN)
  1133. LPITEMIDLIST pidl = {0};
  1134. ::SHGetSpecialFolderLocation(NULL, CSIDL_STARTUP, &pidl);
  1135. tchar_t szBuff[MAX_PATH + 1] = {0};
  1136. ::SHGetPathFromIDList(pidl, szBuff);
  1137. sDir = QString("file:///%1") + qS2QS(szBuff);
  1138. #else
  1139. #pragma message "TODO: Unix part"
  1140. #endif
  1141. }
  1142. bool bRv = QDesktopServices::openUrl( QUrl(sDir) );
  1143. xTEST_EQ(true, bRv);
  1144. }
  1145. #endif
  1146. //------------------------------------------------------------------------------
  1147. #if defined(Q_OS_WIN)
  1148. void
  1149. CMain::mnuDirs_OnSendTo() {
  1150. QString sDir;
  1151. {
  1152. LPITEMIDLIST pidl = {0};
  1153. ::SHGetSpecialFolderLocation(NULL, CSIDL_SENDTO, &pidl);
  1154. tchar_t szBuff[MAX_PATH + 1] = {0};
  1155. ::SHGetPathFromIDList(pidl, szBuff);
  1156. sDir = QString("file:///%1") + qS2QS(szBuff);
  1157. }
  1158. bool bRv = QDesktopServices::openUrl( QUrl(sDir) );
  1159. xTEST_EQ(true, bRv);
  1160. }
  1161. #endif
  1162. //------------------------------------------------------------------------------
  1163. void
  1164. CMain::mnuDirs_OnTemp() {
  1165. cQString csDir = QString("file:///%1")
  1166. .arg(QStandardPaths::writableLocation(QStandardPaths::TempLocation));
  1167. bool bRv = QDesktopServices::openUrl( QUrl(csDir) );
  1168. xTEST_EQ(true, bRv);
  1169. }
  1170. //------------------------------------------------------------------------------
  1171. void
  1172. CMain::mnuDirs_OnNetwork() {
  1173. #if defined(Q_OS_WIN)
  1174. LPITEMIDLIST lst = {0};
  1175. SHELLEXECUTEINFO se = {0};
  1176. ::SHGetSpecialFolderLocation(NULL, CSIDL_NETWORK, &lst);
  1177. se.cbSize = sizeof(se);
  1178. se.fMask = SEE_MASK_IDLIST;
  1179. se.hwnd = NULL;
  1180. se.lpVerb = xT("open");
  1181. se.nShow = SW_SHOW;
  1182. se.lpIDList = lst;
  1183. ::ShellExecuteEx(&se);
  1184. (void)::CoTaskMemFree(lst);
  1185. #else
  1186. QString sFile;
  1187. cQString csDesktop = QString().fromStdString( CxSystemInfo().desktopName() );
  1188. if ("gnome" == csDesktop) {
  1189. sFile = "/usr/bin/gnome-network-properties";
  1190. }
  1191. else if ("kde" == csDesktop || "kde-plasma" == csDesktop) {
  1192. #pragma message "TODO: mnuDirs_OnNetwork"
  1193. sFile = "/usr/bin/knetworkmanager";
  1194. }
  1195. else if ("xfce" == csDesktop) {
  1196. #pragma message "TODO: mnuDirs_OnNetwork"
  1197. sFile = "";
  1198. }
  1199. else {
  1200. sFile = "";
  1201. }
  1202. QString sDir = QString("file:///%1").arg(sFile);
  1203. bool bRv = QDesktopServices::openUrl( QUrl(sDir) );
  1204. xTEST_EQ(true, bRv);
  1205. #endif
  1206. }
  1207. //------------------------------------------------------------------------------
  1208. void
  1209. CMain::mnuDirs_OnTrash() {
  1210. #if defined(Q_OS_WIN)
  1211. LPITEMIDLIST lst = {0};
  1212. SHELLEXECUTEINFO se = {0};
  1213. ::SHGetSpecialFolderLocation(NULL, CSIDL_BITBUCKET, &lst);
  1214. se.cbSize = sizeof(se);
  1215. se.fMask = SEE_MASK_IDLIST;
  1216. se.hwnd = NULL;
  1217. se.lpVerb = xT("open");
  1218. se.nShow = SW_SHOW;
  1219. se.lpIDList = lst;
  1220. ::ShellExecuteEx(&se);
  1221. (void)::CoTaskMemFree(lst);
  1222. #else
  1223. cQString csDir = QString("file:///%1/%2")
  1224. .arg(QStandardPaths::standardLocations(QStandardPaths::HomeLocation).toVector().at(0))
  1225. .arg(SPECIAL_RELATIVE_DIR_TRASH);
  1226. bool bRv = QDesktopServices::openUrl( QUrl(csDir) );
  1227. xTEST_EQ(true, bRv);
  1228. #endif
  1229. }
  1230. //------------------------------------------------------------------------------
  1231. /*******************************************************************************
  1232. * _m_tabLinks
  1233. *
  1234. *******************************************************************************/
  1235. //------------------------------------------------------------------------------
  1236. void
  1237. CMain::mnuLinks_OnShow(
  1238. const QPoint &a_point
  1239. )
  1240. {
  1241. _m_bIsAllowWrap = false;
  1242. qCHECK_DO(true == a_point.isNull(), return);
  1243. QMenu mnuLinks(this);
  1244. // actions
  1245. QAction *acTabAdd = new QAction(tr("Tab add"), this);
  1246. connect(acTabAdd, &QAction::triggered,
  1247. this, &CMain::mnuLinks_OnTabAdd);
  1248. QAction *acTabRemove = new QAction(tr("Tab remove"), this);
  1249. connect(acTabRemove, &QAction::triggered,
  1250. this, &CMain::mnuLinks_OnTabRemove);
  1251. QAction *acTabRename = new QAction(tr("Tab rename"), this);
  1252. connect(acTabRename, &QAction::triggered,
  1253. this, &CMain::mnuLinks_OnTabRename);
  1254. // add actions
  1255. mnuLinks.addAction(acTabAdd);
  1256. mnuLinks.addAction(acTabRemove);
  1257. mnuLinks.addAction(acTabRename);
  1258. mnuLinks.exec( _m_tabLinks->mapToGlobal(a_point) );
  1259. _m_bIsAllowWrap = true;
  1260. }
  1261. //------------------------------------------------------------------------------
  1262. void
  1263. CMain::mnuLinks_OnTabAdd() {
  1264. // Get table name
  1265. QString sTabName;
  1266. {
  1267. QInputDialog idlgInputDialog(this);
  1268. cint ciRv = idlgInputDialog.exec();
  1269. switch (ciRv) {
  1270. case QDialog::Rejected:
  1271. return;
  1272. break;
  1273. case QDialog::Accepted:
  1274. qCHECK_DO(true == idlgInputDialog.textValue().isEmpty(), return);
  1275. sTabName = idlgInputDialog.textValue();
  1276. break;
  1277. default:
  1278. xTEST_FAIL;
  1279. break;
  1280. }
  1281. }
  1282. // to UI
  1283. {
  1284. _tabPageAddEmpty(sTabName);
  1285. _tabPageShow(sTabName);
  1286. }
  1287. }
  1288. //------------------------------------------------------------------------------
  1289. void
  1290. CMain::mnuLinks_OnTabRemove() {
  1291. // ask for removing
  1292. {
  1293. cQString csText = tr("Remove the tab and all its content?");
  1294. cint ciRv = QMessageBox::question(this, qApp->applicationName(), csText,
  1295. QMessageBox::Ok | QMessageBox::No);
  1296. switch (ciRv) {
  1297. case QMessageBox::Ok:
  1298. xNA;
  1299. break;
  1300. default:
  1301. case QMessageBox::No:
  1302. return;
  1303. break;
  1304. }
  1305. }
  1306. cQString csTabName = _m_tabLinks->tabText( _m_tabLinks->currentIndex() );
  1307. // to DB
  1308. {
  1309. // from t_tabs
  1310. {
  1311. QSqlQuery qryDelete(_m_dbDatabase);
  1312. cQString csSql = \
  1313. "DELETE FROM t_tabs WHERE f_name=:p_tab_name;";
  1314. bool bRv = qryDelete.prepare(csSql);
  1315. qCHECK_REF(bRv, qryDelete)
  1316. qryDelete.bindValue(":p_tab_name", csTabName);
  1317. bRv = qryDelete.exec();
  1318. qCHECK_REF(bRv, qryDelete);
  1319. }
  1320. // from t_main
  1321. {
  1322. QSqlQuery qryDelete(_m_dbDatabase);
  1323. cQString csSql = \
  1324. "DELETE FROM t_main WHERE f_tab_index=:p_tab_index";
  1325. bool bRv = qryDelete.prepare(csSql);
  1326. qCHECK_REF(bRv, qryDelete)
  1327. qryDelete.bindValue(":p_tab_index", _m_tabLinks->currentIndex());
  1328. bRv = qryDelete.exec();
  1329. qCHECK_REF(bRv, qryDelete);
  1330. }
  1331. }
  1332. // to UI
  1333. {
  1334. _m_tabLinks->removeTab( _m_tabLinks->currentIndex() );
  1335. }
  1336. }
  1337. //------------------------------------------------------------------------------
  1338. void
  1339. CMain::mnuLinks_On

Large files files are truncated, but you can click here to view the full file