PageRenderTime 51ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/src/schat/widget/sendwidget.cpp

http://schat.googlecode.com/
C++ | 626 lines | 453 code | 99 blank | 74 comment | 105 complexity | fb932133e3bba765dad6e4d2fea131e1 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.1
  1. /* $Id: sendwidget.cpp 2264 2012-02-05 12:20:38Z IMPOMEZIA $
  2. * IMPOMEZIA Simple Chat
  3. * Copyright Š 2008-2012 IMPOMEZIA <schat@impomezia.com>
  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 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program 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
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include <QAction>
  19. #include <QContextMenuEvent>
  20. #include <QDesktopServices>
  21. #include <QGridLayout>
  22. #include <QMenu>
  23. #include <QToolBar>
  24. #include <QWidgetAction>
  25. #include "3rdparty/qtwin.h"
  26. #include "abstractprofile.h"
  27. #include "colorbutton.h"
  28. #include "emoticons/emoticonselector.h"
  29. #include "settings.h"
  30. #include "settingsdialog.h"
  31. #include "soundaction.h"
  32. #include "widget/nickedit.h"
  33. #include "widget/sendwidget.h"
  34. /*!
  35. * ??????????? ?????? SendWidget.
  36. */
  37. SendWidget::SendWidget(QWidget *parent)
  38. : TranslateWidget(parent),
  39. m_bigSendButton(SimpleSettings->getBool("BigSendButton")),
  40. m_input(new InputWidget(this)),
  41. m_toolBar(0)
  42. {
  43. m_availableActions << "bold" << "italic" << "underline" << "color" << "emoticons" << "stretch" << "log" << "send" << "separator" << "strike";
  44. createPermanentButtons();
  45. initToolBar();
  46. setSettings();
  47. QGridLayout *mainLay = new QGridLayout(this);
  48. #ifndef Q_OS_WINCE
  49. mainLay->addWidget(m_toolBar, 0, 0);
  50. mainLay->addWidget(m_input, 1, 0);
  51. #else
  52. mainLay->addWidget(m_input, 0, 0);
  53. mainLay->addWidget(m_toolBar, 1, 0);
  54. #endif
  55. if (m_bigSendButton && m_send)
  56. mainLay->addWidget(m_send, 0, 1, 2, 1);
  57. mainLay->setMargin(0);
  58. mainLay->setSpacing(0);
  59. connect(m_input, SIGNAL(sendMsg(const QString &)), SIGNAL(sendMsg(const QString &)));
  60. connect(m_input, SIGNAL(needCopy()), SIGNAL(needCopy()));
  61. connect(SimpleSettings, SIGNAL(changed(int)), SLOT(setSettings()));
  62. connect(m_input, SIGNAL(cursorPositionChanged()), SLOT(cursorPositionChanged()));
  63. retranslateUi();
  64. }
  65. /*!
  66. * ?????????? ????: ????????? ?? ???????? ? ???? ???????????.
  67. */
  68. QPair<SoundAction*, bool> SendWidget::soundAction() const
  69. {
  70. QPair<SoundAction*, bool> pair(m_soundAction, m_availableActions.contains("sound"));
  71. return pair;
  72. }
  73. QToolButton* SendWidget::settingsButton() const
  74. {
  75. if (m_availableActions.contains("settings"))
  76. return m_settingsButton;
  77. return 0;
  78. }
  79. void SendWidget::setInputFocus()
  80. {
  81. m_input->setFocus();
  82. }
  83. void SendWidget::setStyleSheet()
  84. {
  85. if (!m_toolBar)
  86. return;
  87. #if !defined(Q_OS_MAC)
  88. #if defined(Q_WS_WIN)
  89. m_toolBar->setStyleSheet(QString("QToolBar { background-color: %1; margin:0px; border:0px; }").arg(palette().color(QPalette::Window).name()));
  90. #else
  91. m_toolBar->setStyleSheet("QToolBar { margin:0px; border:0px; }");
  92. #endif
  93. #endif
  94. }
  95. /*!
  96. * \brief ????????? ????????? ??????? ??????? ??? ?????????? ??????.
  97. */
  98. void SendWidget::cursorPositionChanged()
  99. {
  100. QTextCursor cursor = m_input->textCursor();
  101. if (cursor.hasSelection()) {
  102. int position = cursor.position();
  103. if (position < cursor.anchor())
  104. cursor.setPosition(position + 1);
  105. }
  106. QTextCharFormat charFormat = cursor.charFormat();
  107. if (m_bold) m_bold->setChecked(charFormat.font().bold());
  108. if (m_italic) m_italic->setChecked(charFormat.font().italic());
  109. if (m_underline) m_underline->setChecked(charFormat.font().underline());
  110. if (m_strike) m_strike->setChecked(charFormat.font().strikeOut());
  111. if (m_color) m_color->setAltColor(charFormat.foreground().color());
  112. }
  113. void SendWidget::log()
  114. {
  115. QDesktopServices::openUrl(QUrl::fromLocalFile(SimpleSettings->path(Settings::LogPath).at(0)));
  116. }
  117. /*!
  118. * ????????? ????????? ????? "??????????" \a Ctrl+B.
  119. */
  120. void SendWidget::setBold(bool b)
  121. {
  122. QTextCharFormat format;
  123. format.setFontWeight(b ? QFont::Bold : QFont::Normal);
  124. mergeFormat(format);
  125. }
  126. /*!
  127. * \brief ????????? ????????? ????? "??????" \a Ctrl+I.
  128. */
  129. void SendWidget::setItalic(bool b)
  130. {
  131. QTextCharFormat format;
  132. format.setFontItalic(b);
  133. mergeFormat(format);
  134. }
  135. void SendWidget::setSettings()
  136. {
  137. if (m_emoticons) m_emoticons->setEnabled(SimpleSettings->getBool("UseEmoticons"));
  138. }
  139. /*!
  140. * ????????? ????????? ????? "???????????".
  141. */
  142. void SendWidget::setStrike(bool b)
  143. {
  144. QTextCharFormat format;
  145. format.setFontStrikeOut(b);
  146. mergeFormat(format);
  147. }
  148. void SendWidget::settingsPage()
  149. {
  150. QAction *action = qobject_cast<QAction *>(sender());
  151. if (action)
  152. emit showSettingsPage(action->data().toInt());
  153. }
  154. /*!
  155. * ????????? ????????? ????? "????????????" \a Ctrl+U.
  156. */
  157. void SendWidget::setUnderline(bool b)
  158. {
  159. QTextCharFormat format;
  160. format.setFontUnderline(b);
  161. mergeFormat(format);
  162. }
  163. void SendWidget::textColor(const QColor &color)
  164. {
  165. if (!color.isValid())
  166. return;
  167. QTextCharFormat format;
  168. format.setForeground(color);
  169. mergeFormat(format);
  170. }
  171. /*!
  172. * ?????? ???????.
  173. */
  174. bool SendWidget::eventFilter(QObject *object, QEvent *event)
  175. {
  176. if (event->type() == QEvent::ContextMenu) {
  177. QContextMenuEvent *menuEvent = static_cast<QContextMenuEvent *>(event);
  178. QMenu menu(this);
  179. QMenu *addMenu = availableActions();
  180. if (addMenu)
  181. menu.addMenu(addMenu);
  182. QAction *removeAction = 0;
  183. QAction *action = m_toolBar->actionAt(menuEvent->pos());
  184. QString name;
  185. if (action) {
  186. name = action->data().toString();
  187. if (!name.isEmpty()) {
  188. removeAction = menu.addAction(QIcon(":/images/edit-delete.png"), tr("Delete"));
  189. }
  190. }
  191. QAction *resetAction = 0;
  192. QStringList list = toolBarLayout();
  193. if (m_bigSendButton && !list.contains("send"))
  194. list << "send";
  195. if (list != schat::DefaultToolBarLayout) {
  196. menu.addSeparator();
  197. resetAction = menu.addAction(QIcon(":/images/undo.png"), tr("Default"));
  198. }
  199. QAction *result = menu.exec(menuEvent->globalPos());
  200. if (result) {
  201. if (result == removeAction) {
  202. m_toolBar->removeAction(action);
  203. if (!m_permanentButtons.contains(name))
  204. action->deleteLater();
  205. if (!m_availableActions.contains(name))
  206. m_availableActions << name;
  207. }
  208. else if (result == resetAction) {
  209. clearToolBar();
  210. buildToolBar(schat::DefaultToolBarLayout, false);
  211. }
  212. else {
  213. QString name = result->data().toString();
  214. if (!name.isEmpty()) {
  215. createAction(name, action);
  216. }
  217. }
  218. saveToolBarLayout();
  219. }
  220. return true;
  221. }
  222. else if (m_settingsButton->menu() == object && event->type() == QEvent::KeyPress) {
  223. if (static_cast<QKeyEvent *>(event)->modifiers() == Qt::AltModifier)
  224. return true;
  225. }
  226. return QWidget::eventFilter(object, event);
  227. }
  228. /*!
  229. * ???????? ?????? ?? ?????? ????????????.
  230. *
  231. * \param name ?????????? ??? ??????.
  232. * \param before ?????? ????? ????????? ?? ???? ??????, ???? 0, ?? ?????? ????? ????????? ? ?????.
  233. * \return ????????? ?? ????????? ?????? QAction, ??? 0 ? ?????? ??????.
  234. */
  235. QAction* SendWidget::createAction(const QString &name, QAction *before)
  236. {
  237. QString lowerName = name.toLower();
  238. if (!m_availableActions.contains(name))
  239. return 0;
  240. QAction *action = 0;
  241. if (lowerName == "bold") {
  242. action = m_toolBar->addAction(QIcon(":/images/format-text-bold.png"), "", this, SLOT(setBold(bool)));
  243. action->setCheckable(true);
  244. action->setShortcut(Qt::CTRL + Qt::Key_B);
  245. m_bold = action;
  246. }
  247. else if (lowerName == "italic") {
  248. action = m_toolBar->addAction(QIcon(":/images/format-text-italic.png"), "", this, SLOT(setItalic(bool)));
  249. action->setCheckable(true);
  250. action->setShortcut(Qt::CTRL + Qt::Key_I);
  251. m_italic = action;
  252. }
  253. else if (lowerName == "underline") {
  254. action = m_toolBar->addAction(QIcon(":/images/format-text-underline.png"), "", this, SLOT(setUnderline(bool)));
  255. action->setCheckable(true);
  256. action->setShortcut(Qt::CTRL + Qt::Key_U);
  257. m_underline = action;
  258. }
  259. else if (lowerName == "strike") {
  260. action = m_toolBar->addAction(QIcon(":/images/format-text-strikethrough.png"), "", this, SLOT(setStrike(bool)));
  261. action->setCheckable(true);
  262. m_strike = action;
  263. }
  264. else if (lowerName == "settings") {
  265. action = m_toolBar->addWidget(m_settingsButton);
  266. action->setVisible(true);
  267. }
  268. else if (lowerName == "separator") {
  269. action = m_toolBar->addSeparator();
  270. }
  271. else if (lowerName == "color") {
  272. if (!m_color) {
  273. m_color = new ColorButton(m_input->textColor(), this);
  274. connect(m_color, SIGNAL(newColor(const QColor &)), SLOT(textColor(const QColor &)));
  275. }
  276. action = m_toolBar->addWidget(m_color);
  277. }
  278. else if (lowerName == "emoticons") {
  279. QMenu *menu = new QMenu(this);
  280. EmoticonSelector *emoticonSelector = new EmoticonSelector(this);
  281. QWidgetAction *act = new QWidgetAction(this);
  282. act->setDefaultWidget(emoticonSelector);
  283. menu->addAction(act);
  284. connect(menu, SIGNAL(aboutToShow()), emoticonSelector, SLOT(prepareList()));
  285. connect(menu, SIGNAL(aboutToHide()), emoticonSelector, SLOT(aboutToHide()));
  286. connect(emoticonSelector, SIGNAL(itemSelected(const QString &)), m_input, SLOT(insertPlainText(const QString &)));
  287. m_emoticons = new QToolButton(this);
  288. m_emoticons->setIcon(QIcon(":/images/emoticon.png"));
  289. m_emoticons->setAutoRaise(true);
  290. m_emoticons->setMenu(menu);
  291. m_emoticons->setPopupMode(QToolButton::InstantPopup);
  292. m_emoticons->setShortcut(Qt::CTRL + Qt::Key_E);
  293. action = m_toolBar->addWidget(m_emoticons);
  294. }
  295. else if (lowerName == "stretch") {
  296. QWidget *stretch = new QWidget(this);
  297. stretch->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
  298. action = m_toolBar->addWidget(stretch);
  299. }
  300. else if (lowerName == "sound") {
  301. m_toolBar->addAction(m_soundAction);
  302. action = m_soundAction;
  303. }
  304. else if (lowerName == "log") {
  305. action = m_toolBar->addAction(QIcon(":/images/book.png"), "", this, SLOT(log()));
  306. m_logAction = action;
  307. }
  308. else if (lowerName == "send") {
  309. m_send = new QToolButton(this);
  310. m_send->setAutoRaise(true);
  311. connect(m_send, SIGNAL(clicked()), m_input, SLOT(sendMsg()));
  312. if (m_bigSendButton) {
  313. m_send->setIcon(QIcon(":/images/go-jump-locationbar-v.png"));
  314. #ifdef SCHAT_WINCE_VGA
  315. m_send->setIconSize(QSize(55, 72));
  316. #else
  317. m_send->setIconSize(QSize(27, 36));
  318. #endif
  319. }
  320. else {
  321. m_send->setIcon(QIcon(":/images/go-jump-locationbar.png"));
  322. action = m_toolBar->addWidget(m_send);
  323. }
  324. }
  325. if (action) {
  326. m_availableActions.removeAll(lowerName);
  327. action->setData(lowerName);
  328. if (lowerName != "separator" && !m_availableActions.contains("separator"))
  329. m_availableActions << "separator";
  330. if (before) {
  331. m_toolBar->removeAction(action);
  332. m_toolBar->insertAction(before, action);
  333. }
  334. }
  335. return action;
  336. }
  337. QAction* SendWidget::createSettingsPage(const QIcon &icon, int page)
  338. {
  339. QAction *action = m_prefMenu->addAction(icon, "", this, SLOT(settingsPage()));
  340. action->setData(page);
  341. return action;
  342. }
  343. /*!
  344. * ??????? ?????? ??????.
  345. */
  346. QStringList SendWidget::toolBarLayout() const
  347. {
  348. QStringList out;
  349. foreach (QAction *action, m_toolBar->actions()) {
  350. QString name = action->data().toString();
  351. if (!name.isEmpty())
  352. out << name;
  353. }
  354. return out;
  355. }
  356. /*!
  357. * ????????? ???? ? ?????????? ???????? ??? ?????????? ?? ?????? ????????????.
  358. *
  359. * \return ?????????? ?????????????? ????, ??? 0 ???? ??? ????????? ??????.
  360. */
  361. QMenu* SendWidget::availableActions()
  362. {
  363. if (m_availableActions.isEmpty())
  364. return 0;
  365. QMenu *menu = new QMenu(tr("Add"), this);
  366. menu->setIcon(QIcon(":/images/edit-add.png"));
  367. availableAction(menu, "bold", QIcon(":/images/format-text-bold.png"), tr("Bold"));
  368. availableAction(menu, "italic", QIcon(":/images/format-text-italic.png"), tr("Italic"));
  369. availableAction(menu, "underline", QIcon(":/images/format-text-underline.png"), tr("Underline"));
  370. availableAction(menu, "strike", QIcon(":/images/format-text-strikethrough.png"), tr("Strikeout"));
  371. #ifdef Q_OS_WINCE
  372. availableAction(menu, "settings", QIcon(":/images/configure.png"), tr("Preferences"));
  373. #endif
  374. availableAction(menu, "color", QIcon(":/images/color.png"), tr("Color"));
  375. availableAction(menu, "emoticons", QIcon(":/images/emoticon.png"), tr("Emoticons"));
  376. availableAction(menu, "log", QIcon(":/images/book.png"), tr("Logs"));
  377. #ifdef Q_OS_WINCE
  378. availableAction(menu, "sound", QIcon(":/images/sound.png"), tr("Sound"));
  379. #endif
  380. availableAction(menu, "send", QIcon(":/images/go-jump-locationbar.png"), tr("Send"));
  381. bool separator = false;
  382. if (m_availableActions.contains("separator")) {
  383. separator = true;
  384. menu->addSeparator();
  385. menu->addAction(tr("Separator"))->setData("separator");
  386. }
  387. if (m_availableActions.contains("stretch")) {
  388. if (!separator)
  389. menu->addSeparator();
  390. menu->addAction(tr("Stretch"))->setData("stretch");
  391. }
  392. if (menu->actions().isEmpty()) {
  393. menu->deleteLater();
  394. return 0;
  395. }
  396. else
  397. return menu;
  398. }
  399. void SendWidget::availableAction(QMenu *menu, const QString &name, const QIcon &icon, const QString &text) const
  400. {
  401. if (m_availableActions.contains(name))
  402. menu->addAction(icon, text)->setData(name);
  403. }
  404. /*!
  405. * ???????? ?????? ?? ?????? ???????????? ?? ??????.
  406. *
  407. * \param actions ?????? ??????.
  408. * \param forceSend ????????????? ?????????? ?????? ????????, ??? ????????????? ??????? ?????? ????????.
  409. */
  410. void SendWidget::buildToolBar(const QStringList &actions, bool forceSend)
  411. {
  412. foreach (QString name, actions) {
  413. createAction(name);
  414. }
  415. if (forceSend && m_bigSendButton && !actions.contains("send"))
  416. createAction("send");
  417. saveToolBarLayout();
  418. }
  419. /*!
  420. * ??????? ?????? ???????????? ?? ??????.
  421. */
  422. void SendWidget::clearToolBar()
  423. {
  424. QList<QAction *> list = m_toolBar->actions();
  425. m_toolBar->clear();
  426. foreach (QAction *a, list) {
  427. QString name = a->data().toString();
  428. if (!name.isEmpty() && !m_availableActions.contains(name))
  429. m_availableActions << name;
  430. if (!m_permanentButtons.contains(name))
  431. a->deleteLater();
  432. }
  433. }
  434. /*!
  435. * ???????? ?????? ?????????.
  436. */
  437. void SendWidget::createPermanentButtons()
  438. {
  439. m_settingsButton = new QToolButton(this);
  440. m_settingsButton->setIcon(QIcon(":/images/configure.png"));
  441. m_settingsButton->setAutoRaise(true);
  442. m_settingsButton->setPopupMode(QToolButton::InstantPopup);
  443. m_settingsButton->setVisible(false);
  444. QMenu *menu = new QMenu(m_settingsButton);
  445. menu->installEventFilter(this);
  446. QWidgetAction *act = new QWidgetAction(this);
  447. NickEdit *nickEdit = new NickEdit(this, NickEdit::GenderButton | NickEdit::ApplyButton);
  448. nickEdit->setMargin(2);
  449. act->setDefaultWidget(nickEdit);
  450. menu->addAction(act);
  451. menu->addSeparator();
  452. m_prefMenu = menu->addMenu(QIcon(":/images/configure2.png"), "");
  453. m_profilePage = createSettingsPage(QIcon(":/images/profile.png"), SettingsDialog::ProfilePage);
  454. m_networkPage = createSettingsPage(QIcon(":/images/network.png"), SettingsDialog::NetworkPage);
  455. m_interfacePage = createSettingsPage(QIcon(":/images/applications-graphics.png"), SettingsDialog::InterfacePage);
  456. m_emoticonsPage = createSettingsPage(QIcon(":/images/emoticon.png"), SettingsDialog::EmoticonsPage);
  457. m_soundPage = createSettingsPage(QIcon(":/images/sound.png"), SettingsDialog::SoundPage);
  458. m_notificationPage = createSettingsPage(QIcon(":/images/notification.png"), SettingsDialog::NotificationPage);
  459. m_statusesPage = createSettingsPage(QIcon(":/images/statuses.png"), SettingsDialog::StatusesPage);
  460. m_miscPage = createSettingsPage(QIcon(":/images/application-x-desktop.png"), SettingsDialog::MiscPage);
  461. m_aboutAction = menu->addAction("", this, SIGNAL(about()));
  462. if (Settings::isNewYear())
  463. m_aboutAction->setIcon(QIcon(":/images/schat16-ny.png"));
  464. else
  465. m_aboutAction->setIcon(QIcon(":/images/schat16.png"));
  466. menu->addSeparator();
  467. m_quitAction = menu->addAction(QIcon(":/images/exit.png"), "", this, SIGNAL(closeChat()));
  468. #if QT_VERSION >= 0x040600
  469. m_quitAction->setShortcut(QKeySequence::Quit);
  470. #endif
  471. m_settingsButton->setMenu(menu);
  472. m_soundAction = new SoundAction(this);
  473. m_permanentButtons << "settings" << "sound";
  474. m_availableActions << m_permanentButtons;
  475. }
  476. /*!
  477. * ????????????? ?????? ????????????.
  478. */
  479. void SendWidget::initToolBar()
  480. {
  481. m_toolBar = new QToolBar(this);
  482. m_toolBar->setAttribute(Qt::WA_NoSystemBackground, false);
  483. m_toolBar->installEventFilter(this);
  484. #if !defined(Q_OS_WINCE)
  485. m_toolBar->setIconSize(QSize(16, 16));
  486. #elif defined(SCHAT_WINCE_VGA)
  487. m_toolBar->setIconSize(QSize(36, 36));
  488. #endif
  489. setStyleSheet();
  490. buildToolBar(SimpleSettings->getList("ToolBarLayout"));
  491. }
  492. /*!
  493. * ??????? ???????.
  494. */
  495. void SendWidget::mergeFormat(const QTextCharFormat &format)
  496. {
  497. QTextCursor cursor = m_input->textCursor();
  498. cursor.mergeCharFormat(format);
  499. m_input->mergeCurrentCharFormat(format);
  500. }
  501. void SendWidget::retranslateUi()
  502. {
  503. m_settingsButton->setToolTip(tr("Menu"));
  504. m_prefMenu->setTitle(tr("Preferences"));
  505. m_aboutAction->setText(tr("About Simple Chat..."));
  506. m_quitAction->setText(tr("Quit"));
  507. m_soundAction->retranslateUi();
  508. m_profilePage->setText(tr("Personal data..."));
  509. m_networkPage->setText(tr("Network..."));
  510. m_interfacePage->setText(tr("Interface..."));
  511. m_emoticonsPage->setText(tr("Emoticons..."));
  512. m_soundPage->setText(tr("Sounds..."));
  513. m_notificationPage->setText(tr("Notifications..."));
  514. m_statusesPage->setText(tr("Statuses..."));
  515. m_miscPage->setText(tr("Others..."));
  516. if (m_bold) m_bold->setText(tr("Bold"));
  517. if (m_italic) m_italic->setText(tr("Italic"));
  518. if (m_underline) m_underline->setText(tr("Underline"));
  519. if (m_strike) m_strike->setText(tr("Strikeout"));
  520. if (m_emoticons) m_emoticons->setToolTip(tr("Add emoticon"));
  521. if (m_logAction) m_logAction->setText(tr("Logs"));
  522. if (m_send) m_send->setToolTip(tr("Send"));
  523. }
  524. void SendWidget::saveToolBarLayout()
  525. {
  526. SimpleSettings->setList("ToolBarLayout", toolBarLayout());
  527. }