PageRenderTime 27ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/qutim-0.3.1/plugins/winintegration/libs/qtwrapper/src/TaskbarPreviews.cpp

#
C++ | 467 lines | 382 code | 55 blank | 30 comment | 60 complexity | 7dc5b937daf07abf5863d0ff8f7c0faf MD5 | raw file
Possible License(s): CC-BY-SA-4.0, GPL-3.0, LGPL-2.1, GPL-2.0
  1. /****************************************************************************
  2. **
  3. ** qutIM - instant messenger
  4. **
  5. ** Copyright Š 2011 Ivan Vizir <define-true-false@yandex.com>
  6. **
  7. *****************************************************************************
  8. **
  9. ** $QUTIM_BEGIN_LICENSE$
  10. ** This program is free software: you can redistribute it and/or modify
  11. ** it under the terms of the GNU General Public License as published by
  12. ** the Free Software Foundation, either version 3 of the License, or
  13. ** (at your option) any later version.
  14. **
  15. ** This program is distributed in the hope that it will be useful,
  16. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  18. ** See the GNU General Public License for more details.
  19. **
  20. ** You should have received a copy of the GNU General Public License
  21. ** along with this program. If not, see http://www.gnu.org/licenses/.
  22. ** $QUTIM_END_LICENSE$
  23. **
  24. ****************************************************************************/
  25. #include "TaskbarPreviews.h"
  26. #include "WinEventFilter.h"
  27. #include <QTimer>
  28. #include <QApplication>
  29. #include "../../apilayer/src/ApiTaskbarPreviews.h"
  30. TaskbarPreviews::_tab::_tab()
  31. {
  32. memset(this, 0, sizeof(_tab));
  33. static unsigned nextid = 0;
  34. this->id = ++nextid;
  35. }
  36. ///////////////////////////////////////////////////////////////////////////////
  37. // Functions, related to TaskbarPreviews class itself
  38. TaskbarPreviews::TaskbarPreviews()
  39. {
  40. Win7EventFilter::instance(); // initializing filter
  41. }
  42. unsigned TaskbarPreviews::addTab(QWidget *tab, QWidget *owner, const QString &title, QWidget *before, PreviewProvider *pp)
  43. {
  44. _tab t;
  45. t.internalTabWidget = new QWidget;
  46. t.pp = pp;
  47. t.userTabWidget = tab;
  48. t.tabHandle = t.internalTabWidget->winId();
  49. t.userTabOwner = owner;
  50. t.type = (tab->window() == tab) ? ttWindow : ttWidget;
  51. if (!title.isNull())
  52. t.internalTabWidget->setWindowTitle(title);
  53. else
  54. t.internalTabWidget->setWindowTitle(t.userTabOwner->windowTitle());
  55. HWND afterHwnd = before ? static_cast<HWND>(m_tabs.internal(before)->winId()) : 0; // will return zero if after == 0 or there's no such tab, in that cases tab will be added to the end
  56. if (tab->window() == tab) {
  57. if(pp){
  58. ForceIconicRepresentation(t.internalTabWidget->winId());
  59. }
  60. } else // tab is not a window so previews must be created by library or user anyway
  61. ForceIconicRepresentation(t.internalTabWidget->winId());
  62. m_tabs.append(t);
  63. RegisterTab(t.tabHandle, owner->winId());
  64. SetTabOrder(t.tabHandle, afterHwnd);
  65. return t.id;
  66. }
  67. unsigned TaskbarPreviews::addVirtualTab(PreviewProvider *pp, QWidget *owner, const QString &title, QWidget *before)
  68. {
  69. _tab t;
  70. t.internalTabWidget = new QWidget;
  71. t.pp = pp;
  72. t.userTabWidget = 0;
  73. t.tabHandle = t.internalTabWidget->winId();
  74. t.userTabOwner = owner;
  75. t.type = ttVirtual;
  76. if (!title.isNull())
  77. t.internalTabWidget->setWindowTitle(title);
  78. else
  79. t.internalTabWidget->setWindowTitle(t.userTabOwner->windowTitle());
  80. HWND afterHwnd = before ? static_cast<HWND>(m_tabs.internal(before)->winId()) : 0;
  81. ForceIconicRepresentation(t.internalTabWidget->winId());
  82. m_tabs.append(t);
  83. RegisterTab(t.tabHandle, owner->winId());
  84. SetTabOrder(t.tabHandle, afterHwnd);
  85. return t.id;
  86. }
  87. void TaskbarPreviews::setTabTitle(QWidget *tab, const QString &customTitle)
  88. {
  89. QWidget *w = m_tabs.internal(tab);
  90. if (w)
  91. w->setWindowTitle(customTitle);
  92. }
  93. void TaskbarPreviews::setTabTitle(unsigned tabid, const QString &title)
  94. {
  95. QWidget *w = m_tabs.internal(tabid);
  96. if (w)
  97. w->setWindowTitle(title);
  98. }
  99. void TaskbarPreviews::removeTab(QWidget *userWidgetTab)
  100. {
  101. int i = 0;
  102. while(i < m_tabs.size()){
  103. _tab t = m_tabs.at(i);
  104. if(t.userTabWidget == userWidgetTab){
  105. UnregisterTab(t.internalTabWidget->winId());
  106. t.internalTabWidget->deleteLater();
  107. m_tabs.removeAt(i);
  108. }else
  109. i++;
  110. }
  111. }
  112. void TaskbarPreviews::removeTab(unsigned id)
  113. {
  114. int i = 0;
  115. while (i < m_tabs.size()) {
  116. _tab t = m_tabs.at(i);
  117. if (t.id == id) {
  118. UnregisterTab(t.internalTabWidget->winId());
  119. t.internalTabWidget->deleteLater();
  120. m_tabs.removeAt(i);
  121. } else
  122. i++;
  123. }
  124. }
  125. void TaskbarPreviews::activateTab(QWidget *tab)
  126. {
  127. QWidget *internal = m_tabs.internal(tab);
  128. if(internal)
  129. SetTabActive(internal->winId(), m_tabs.owner(internal->winId())->winId());
  130. }
  131. void TaskbarPreviews::activateTab(unsigned id)
  132. {
  133. QWidget *internal = m_tabs.internal(id);
  134. if(internal)
  135. SetTabActive(internal->winId(), m_tabs.owner(internal->winId())->winId());
  136. }
  137. void TaskbarPreviews::changeOrder(QWidget *tab, QWidget *before)
  138. {
  139. QWidget *inttab = m_tabs.internal(tab);
  140. QWidget *intbefore = m_tabs.internal(before);
  141. if(!(inttab && intbefore))
  142. return;
  143. SetTabOrder(inttab->winId(), intbefore->winId());
  144. }
  145. void TaskbarPreviews::changeOrder(QWidget *tab, unsigned beforeid)
  146. {
  147. QWidget *inttab = m_tabs.internal(tab);
  148. QWidget *intbefore = m_tabs.internal(beforeid);
  149. if(!(inttab && intbefore))
  150. return;
  151. SetTabOrder(inttab->winId(), intbefore->winId());
  152. }
  153. void TaskbarPreviews::changeOrder(unsigned tabid, QWidget *before)
  154. {
  155. QWidget *inttab = m_tabs.internal(tabid);
  156. QWidget *intbefore = m_tabs.internal(before);
  157. if(!(inttab && intbefore))
  158. return;
  159. SetTabOrder(inttab->winId(), intbefore->winId());
  160. }
  161. void TaskbarPreviews::changeOrder(unsigned tabid, unsigned beforeid)
  162. {
  163. QWidget *inttab = m_tabs.internal(tabid);
  164. QWidget *intbefore = m_tabs.internal(beforeid);
  165. if(!(inttab && intbefore))
  166. return;
  167. SetTabOrder(inttab->winId(), intbefore->winId());
  168. }
  169. void TaskbarPreviews::widgetDestroyed()
  170. {
  171. QWidget *w = qobject_cast<QWidget *>(sender());
  172. if(w)
  173. removeTab(w);
  174. }
  175. TaskbarPreviews *TaskbarPreviews::instance()
  176. {
  177. static TaskbarPreviews _instance;
  178. return &_instance;
  179. }
  180. void TaskbarPreviews::clear()
  181. {
  182. while(!this->m_tabs.empty())
  183. removeTab(m_tabs.first().userTabWidget);
  184. }
  185. void TaskbarPreviews::refreshPreviews(QWidget *tab)
  186. {
  187. QWidget *w = m_tabs.internal(tab);
  188. if(w)
  189. InvalidateBitmaps(w->winId());
  190. }
  191. void TaskbarPreviews::refreshPreviews(unsigned tabid)
  192. {
  193. QWidget *w = m_tabs.internal(tabid);
  194. if(w)
  195. InvalidateBitmaps(w->winId());
  196. }
  197. // Static functions
  198. unsigned TaskbarPreviews::tabAdd(QWidget *tab, QWidget *owner, const QString &title, QWidget *before, PreviewProvider *pp)
  199. {
  200. return TaskbarPreviews::instance()->addTab(tab, owner, title, before, pp);
  201. }
  202. unsigned TaskbarPreviews::tabAddVirtual(PreviewProvider *pp, QWidget *owner, const QString &title, QWidget *before)
  203. {
  204. return TaskbarPreviews::instance()->addVirtualTab(pp, owner, title, before);
  205. }
  206. void TaskbarPreviews::tabActivate(QWidget *tab)
  207. {
  208. TaskbarPreviews::instance()->activateTab(tab);
  209. }
  210. void TaskbarPreviews::tabActivate(unsigned tabid)
  211. {
  212. TaskbarPreviews::instance()->activateTab(tabid);
  213. }
  214. void TaskbarPreviews::tabRemove(QWidget *tab)
  215. {
  216. TaskbarPreviews::instance()->removeTab(tab);
  217. }
  218. void TaskbarPreviews::tabRemove(unsigned tabid)
  219. {
  220. TaskbarPreviews::instance()->removeTab(tabid);
  221. }
  222. void TaskbarPreviews::tabOrderChange(QWidget *tab, QWidget *before)
  223. {
  224. TaskbarPreviews::instance()->changeOrder(tab, before);
  225. }
  226. void TaskbarPreviews::tabOrderChange(QWidget *tab, unsigned beforeid)
  227. {
  228. TaskbarPreviews::instance()->changeOrder(tab, beforeid);
  229. }
  230. void TaskbarPreviews::tabOrderChange(unsigned tabid, QWidget *before)
  231. {
  232. TaskbarPreviews::instance()->changeOrder(tabid, before);
  233. }
  234. void TaskbarPreviews::tabOrderChange(unsigned tabid, unsigned beforeid)
  235. {
  236. TaskbarPreviews::instance()->changeOrder(tabid, beforeid);
  237. }
  238. void TaskbarPreviews::tabsClear()
  239. {
  240. TaskbarPreviews::instance()->clear();
  241. }
  242. void TaskbarPreviews::tabPreviewsRefresh(QWidget *tab)
  243. {
  244. TaskbarPreviews::instance()->refreshPreviews(tab);
  245. }
  246. void TaskbarPreviews::tabPreviewsRefresh(unsigned tabid)
  247. {
  248. TaskbarPreviews::instance()->refreshPreviews(tabid);
  249. }
  250. void TaskbarPreviews::tabSetTitle(QWidget *tab, const QString &customTitle)
  251. {
  252. TaskbarPreviews::instance()->setTabTitle(tab, customTitle);
  253. }
  254. void TaskbarPreviews::tabSetTitle(unsigned tabid, const QString &title)
  255. {
  256. TaskbarPreviews::instance()->setTabTitle(tabid, title);
  257. }
  258. void TaskbarPreviews::setWindowAttributes(QWidget *window, WindowAttributes wa)
  259. {
  260. if (!window)
  261. return;
  262. SetWindowAttributes(window->winId(), wa);
  263. }
  264. // Functions, used by messages filter.
  265. QPixmap TaskbarPreviews::IconicThumbnail(HWND hwnd, QSize size)
  266. {
  267. QPixmap pixmap;
  268. TabType tt = m_tabs.type(hwnd);
  269. if (tt != ttVirtual) {
  270. QWidget *w = m_tabs.user(hwnd);
  271. PreviewProvider *pp = m_tabs.previews(hwnd);
  272. if (w) {
  273. if(pp)
  274. pixmap = pp->IconicPreview(w, m_tabs.owner(hwnd), size);
  275. else
  276. pixmap = QPixmap::grabWidget(w).scaled(size, Qt::KeepAspectRatio);
  277. }
  278. } else {
  279. unsigned wid = m_tabs.id(hwnd);
  280. PreviewProvider *pp = m_tabs.previews(hwnd);
  281. if(wid)
  282. pixmap = pp->IconicPreview(wid, m_tabs.owner(hwnd), size);
  283. }
  284. return pixmap;
  285. }
  286. QPixmap TaskbarPreviews::IconicLivePreviewBitmap(HWND hwnd)
  287. {
  288. QPixmap pixmap;
  289. TabType tt = m_tabs.type(hwnd);
  290. if (tt != ttVirtual) {
  291. QWidget *w = m_tabs.user(hwnd);
  292. PreviewProvider *pp = m_tabs.previews(hwnd);
  293. if (w) {
  294. if(pp)
  295. pixmap = pp->LivePreview(w, m_tabs.owner(hwnd));
  296. else
  297. pixmap = QPixmap::grabWidget(m_tabs.owner(hwnd));
  298. }
  299. } else {
  300. unsigned wid = m_tabs.id(hwnd);
  301. PreviewProvider *pp = m_tabs.previews(hwnd);
  302. if (wid)
  303. pixmap = pp->LivePreview(wid, m_tabs.owner(hwnd));
  304. }
  305. return pixmap;
  306. }
  307. bool TaskbarPreviews::WasTabActivated(HWND hwnd)
  308. {
  309. QWidget *internal = m_tabs.internal(hwnd);
  310. if (internal) {
  311. QWidget *owner = m_tabs.owner(hwnd);
  312. SetTabActive(internal->winId(), owner->winId());
  313. if (owner->isMinimized())
  314. owner->showNormal();
  315. qApp->setActiveWindow(owner);
  316. emit tabActivated(m_tabs.user(hwnd));
  317. return true;
  318. } else
  319. return false;
  320. }
  321. bool TaskbarPreviews::WasTabRemoved(HWND hwnd)
  322. {
  323. QWidget *internal = m_tabs.internal(hwnd);
  324. if (internal) {
  325. QWidget *owner = m_tabs.owner(hwnd);
  326. bool ignore = false;
  327. emit tabAboutToRemove(m_tabs.user(hwnd), &ignore);
  328. if (!ignore) {
  329. SetNoTabActive(owner->winId());
  330. removeTab(m_tabs.user(hwnd));
  331. }
  332. return true;
  333. } else
  334. return false;
  335. }
  336. ///////////////////////////////////////////////////////////////////////////////
  337. // Functions of TabsList --­ tabs info container.
  338. QWidget *TaskbarPreviews::TabsList::internal(HWND internalHwnd)
  339. {
  340. foreach(const TaskbarPreviews::_tab &t, *this){
  341. if(static_cast<void *>(t.internalTabWidget->winId()) == static_cast<void *>(internalHwnd))
  342. return t.internalTabWidget;
  343. }
  344. return 0;
  345. }
  346. QWidget *TaskbarPreviews::TabsList::internal(QWidget *userWidget)
  347. {
  348. foreach(const TaskbarPreviews::_tab &t, *this){
  349. if(t.userTabWidget == userWidget)
  350. return t.internalTabWidget;
  351. }
  352. return 0;
  353. }
  354. QWidget *TaskbarPreviews::TabsList::internal(unsigned id)
  355. {
  356. foreach(const TaskbarPreviews::_tab &t, *this){
  357. if(t.id == id)
  358. return t.internalTabWidget;
  359. }
  360. return 0;
  361. }
  362. QWidget *TaskbarPreviews::TabsList::user(HWND internalHwnd)
  363. {
  364. foreach(const TaskbarPreviews::_tab &t, *this){
  365. if(static_cast<void *>(t.internalTabWidget->winId()) == static_cast<void *>(internalHwnd))
  366. return t.userTabWidget;
  367. }
  368. return 0;
  369. }
  370. unsigned TaskbarPreviews::TabsList::id(HWND internalHwnd)
  371. {
  372. foreach(const TaskbarPreviews::_tab &t, *this){
  373. if(static_cast<void *>(t.internalTabWidget->winId()) == static_cast<void *>(internalHwnd))
  374. return t.id;
  375. }
  376. return 0;
  377. }
  378. TaskbarPreviews::TabType TaskbarPreviews::TabsList::type(HWND internalHwnd)
  379. {
  380. foreach(const TaskbarPreviews::_tab &t, *this){
  381. if(static_cast<void *>(t.internalTabWidget->winId()) == static_cast<void *>(internalHwnd))
  382. return t.type;
  383. }
  384. return ttUnknown;
  385. }
  386. QWidget *TaskbarPreviews::TabsList::owner(HWND internalHandle)
  387. {
  388. foreach(const TaskbarPreviews::_tab &t, *this){
  389. if(static_cast<void *>(t.internalTabWidget->winId()) == static_cast<void *>(internalHandle))
  390. return t.userTabOwner;
  391. }
  392. return 0;
  393. }
  394. void TaskbarPreviews::TabsList::insert(QWidget *internal, QWidget *userTab, QWidget *tabOwner, PreviewProvider *pp)
  395. {
  396. TaskbarPreviews::_tab t;
  397. connect(userTab, SIGNAL(destroyed()), TaskbarPreviews::instance(), SLOT(widgetDestroyed()));
  398. t.internalTabWidget = internal;
  399. t.userTabWidget = userTab;
  400. t.userTabOwner = tabOwner;
  401. t.tabHandle = static_cast<HWND>(internal->winId());
  402. t.pp = pp;
  403. QList<_tab>::insert(0, t);
  404. }
  405. PreviewProvider *TaskbarPreviews::TabsList::previews(HWND internalHandle)
  406. {
  407. foreach(const TaskbarPreviews::_tab &t, *this){
  408. if(static_cast<void *>(t.internalTabWidget->winId()) == static_cast<void *>(internalHandle))
  409. return t.pp;
  410. }
  411. return 0;
  412. }