Opera 12.15 Source Code
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

scope_desktop_window_manager.cpp 57KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855
  1. /* -*- Mode: c++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*-
  2. **
  3. ** Copyright (C) 2010 Opera Software AS. All rights reserved.
  4. **
  5. ** This file is part of the Opera web browser. It may not be distributed
  6. ** under any circumstances.
  7. */
  8. #include "core/pch.h"
  9. #include "modules/scope/src/scope_transport.h"
  10. #include "adjunct/desktop_scope/src/scope_desktop_window_manager.h"
  11. #include "adjunct/desktop_pi/DesktopPopupMenuHandler.h"
  12. #include "adjunct/desktop_scope/src/scope_widget_info.h"
  13. #include "adjunct/m2_ui/widgets/RichTextEditor.h"
  14. #include "adjunct/quick/Application.h"
  15. #include "adjunct/quick/managers/DesktopClipboardManager.h"
  16. #include "adjunct/quick/managers/SpeedDialManager.h"
  17. #include "adjunct/quick/models/DesktopWindowCollection.h"
  18. #include "adjunct/quick/speeddial/SpeedDialThumbnail.h"
  19. #include "adjunct/quick_toolkit/widgets/OpGroup.h"
  20. #include "adjunct/quick/widgets/OpPagebar.h"
  21. #include "adjunct/quick/windows/BrowserDesktopWindow.h"
  22. #include "adjunct/desktop_util/string/stringutils.h"
  23. #include "adjunct/quick_toolkit/widgets/OpTreeView/OpTreeView.h"
  24. #include "adjunct/quick_toolkit/widgets/QuickComposite.h"
  25. #include "adjunct/quick_toolkit/windows/DesktopWindow.h"
  26. #include "adjunct/quick/widgets/OpAddressDropDown.h"
  27. #include "adjunct/quick/widgets/PagebarButton.h"
  28. #include "adjunct/quick/widgets/OpPagebar.h"
  29. #include "adjunct/quick/widgets/OpPersonalbar.h"
  30. #include "adjunct/desktop_pi/system_input_pi.h"
  31. #include "modules/widgets/WidgetContainer.h"
  32. #include "modules/pi/OpScreenInfo.h"
  33. #include "modules/util/OpTypedObject.h"
  34. #include "modules/widgets/OpWidget.h"
  35. #include "modules/widgets/OpButton.h"
  36. #include "modules/widgets/OpDropDown.h"
  37. // Comment it to have printfs to check timing of events
  38. //#define _DEBUG_SCOPE_TIMING
  39. //#define _DEBUG_SCOPE_TIMING2
  40. /* OpScopeDesktopWindowManager */
  41. OpScopeDesktopWindowManager::OpScopeDesktopWindowManager()
  42. : m_system_input_pi(0)
  43. {
  44. m_last_closed.SetWindowID(0);
  45. m_last_activated.SetWindowID(0);
  46. // Create the system input object
  47. OpStatus::Ignore(SystemInputPI::Create(&m_system_input_pi));
  48. }
  49. /* virtual */
  50. OpScopeDesktopWindowManager::~OpScopeDesktopWindowManager()
  51. {
  52. OP_DELETE(m_system_input_pi);
  53. }
  54. void OpScopeDesktopWindowManager::OnDesktopWindowChanged(DesktopWindow* desktop_window)
  55. {
  56. // Only send the message if scope is enabled
  57. if (!IsEnabled())
  58. return;
  59. #ifdef _DEBUG_SCOPE_TIMING
  60. printf("OnDesktopWindowChanged\n");
  61. #endif // _DEBUG_SCOPE_TIMING
  62. // Build and send the scope event
  63. DesktopWindowInfo info;
  64. RETURN_VOID_IF_ERROR(SetDesktopWindowInfo(info, desktop_window));
  65. RETURN_VOID_IF_ERROR(SendOnWindowUpdated(info));
  66. }
  67. void OpScopeDesktopWindowManager::OnDesktopWindowActivated(DesktopWindow* desktop_window, BOOL active)
  68. {
  69. // Only send the message if scope is enabled and the window is being set to active
  70. if (!IsEnabled() || !active)
  71. return;
  72. #ifdef _DEBUG_SCOPE_TIMING
  73. printf("OnDesktopWindowActivated %s, %s (%d)\n", desktop_window->GetSpecificWindowName(), (desktop_window->GetTitle() ? uni_down_strdup(desktop_window->GetTitle()) : ""), desktop_window->GetID());
  74. #endif // _DEBUG_SCOPE_TIMING
  75. // Build the scope event
  76. DesktopWindowInfo info;
  77. RETURN_VOID_IF_ERROR(SetDesktopWindowInfo(info, desktop_window));
  78. // If there is a window that closed that waits for this activate before having it's closed event sent off
  79. if (m_last_closed.GetWindowID() > 0)
  80. {
  81. #ifdef _DEBUG_SCOPE_TIMING
  82. printf("Sending Delayed Close OnDesktopWindowActivated %s\n", m_last_closed.GetName().UTF8AllocL());
  83. #endif // _DEBUG_SCOPE_TIMING
  84. // Now send the closed event on m_last_closed
  85. RETURN_VOID_IF_ERROR(SendOnWindowClosed(m_last_closed));
  86. // Reset m_last_closed
  87. m_last_closed.SetWindowID(0);
  88. }
  89. // Store the last activated in case it's sent before the closed event
  90. CopyDesktopWindowInfo(info, m_last_activated);
  91. #ifdef _DEBUG_SCOPE_TIMING
  92. printf("Saving last activated OnDesktopWindowActivated %s\n", m_last_activated.GetName().UTF8AllocL());
  93. printf("OnDesktopWindowActivated Sending\n");
  94. #endif // _DEBUG_SCOPE_TIMING
  95. // Send the scope event
  96. RETURN_VOID_IF_ERROR(SendOnWindowActivated(info));
  97. }
  98. void OpScopeDesktopWindowManager::OnDesktopWindowClosing(DesktopWindow* desktop_window, BOOL user_initiated)
  99. {
  100. // Kill the listener since the window is closing
  101. desktop_window->RemoveListener(this);
  102. // Kill the document desktop window listener if this is one
  103. if (desktop_window->GetType() == OpTypedObject::WINDOW_TYPE_DOCUMENT)
  104. static_cast<DocumentDesktopWindow *>(desktop_window)->RemoveDocumentWindowListener(this);
  105. // Only send the message if scope is enabled
  106. if (!IsEnabled())
  107. return;
  108. #ifdef _DEBUG_SCOPE_TIMING
  109. printf("OnDesktopWindowClosing %s, %s (%d)\n", desktop_window->GetSpecificWindowName(), desktop_window->GetTitle() ? uni_down_strdup(desktop_window->GetTitle()) : "", desktop_window->GetID());
  110. #endif // _DEBUG_SCOPE_TIMING
  111. // Build the scope event
  112. DesktopWindowInfo info;
  113. RETURN_VOID_IF_ERROR(SetDesktopWindowInfo(info, desktop_window));
  114. /**
  115. * Note:
  116. * If the parent of the window (dialog) that is being closed is a dialog,
  117. * we need to wait sending the close event
  118. * until after the dialog below gets the activate event
  119. *
  120. * This is to ensure that the active window is correct, because the activated
  121. * event on the window beneath the closing dialog gets the activate event after
  122. * this close
  123. *
  124. * Note: Due to the fact that Windows sends the events in a different order to
  125. * UNIX and mac we also have to check if the last activated window message was
  126. * already sent. If that happens we don't want to delay sending of the
  127. * close message as the activation as already gone
  128. *
  129. */
  130. DesktopWindow* parent = desktop_window->GetParentDesktopWindow();
  131. if (parent && parent->IsDialog() && (!m_last_activated.GetWindowID() || (m_last_activated.GetWindowID() != (UINT32)parent->GetID())))
  132. {
  133. #ifdef _DEBUG_SCOPE_TIMING
  134. printf("Last Activated OnDesktopWindowClosing parent: %s, %s, last_activated: %s\n", parent->GetSpecificWindowName(), parent->GetTitle() ? uni_down_strdup(parent->GetTitle()) : "", m_last_activated.GetName().UTF8AllocL());
  135. #endif // _DEBUG_SCOPE_TIMING
  136. // Reset last activated
  137. m_last_activated.SetWindowID(0);
  138. // Delay sending the close until just before the window underneath is activated
  139. CopyDesktopWindowInfo(info, m_last_closed);
  140. return;
  141. }
  142. // Reset last activated
  143. m_last_activated.SetWindowID(0);
  144. #ifdef _DEBUG_SCOPE_TIMING
  145. printf("OnDesktopWindowClosing Sending\n");
  146. #endif // _DEBUG_SCOPE_TIMING
  147. // Send the scope event
  148. RETURN_VOID_IF_ERROR(SendOnWindowClosed(info));
  149. }
  150. void OpScopeDesktopWindowManager::OnDesktopWindowShown(DesktopWindow* desktop_window, BOOL shown)
  151. {
  152. // Only send the message if scope is enabled and being shown
  153. if (!IsEnabled() || !shown)
  154. return;
  155. #ifdef _DEBUG_SCOPE_TIMING
  156. printf("OnDesktopWindowShown %s, %s (%d)\n", desktop_window->GetSpecificWindowName(), (desktop_window->GetTitle() ? uni_down_strdup(desktop_window->GetTitle()) : ""), desktop_window->GetID());
  157. #endif // _DEBUG_SCOPE_TIMING
  158. // Build and send the scope event
  159. DesktopWindowInfo info;
  160. RETURN_VOID_IF_ERROR(SetDesktopWindowInfo(info, desktop_window));
  161. RETURN_VOID_IF_ERROR(SendOnWindowShown(info));
  162. }
  163. void OpScopeDesktopWindowManager::OnDesktopWindowPageChanged(DesktopWindow* desktop_window)
  164. {
  165. // Only send the message if scope is enabled
  166. if (!IsEnabled())
  167. return;
  168. #ifdef _DEBUG_SCOPE_TIMING
  169. printf("OnDesktopWindowPageChanged %s, %s (%d)\n", desktop_window->GetSpecificWindowName(), (desktop_window->GetTitle() ? uni_down_strdup(desktop_window->GetTitle()) : ""), desktop_window->GetID());
  170. #endif // _DEBUG_SCOPE_TIMING
  171. // Build and send the scope event
  172. DesktopWindowInfo info;
  173. RETURN_VOID_IF_ERROR(SetDesktopWindowInfo(info, desktop_window));
  174. RETURN_VOID_IF_ERROR(SendOnWindowPageChanged(info));
  175. }
  176. ////////////////////////////////////////////////////////////////////////
  177. void OpScopeDesktopWindowManager::OnMenuShown(BOOL shown, QuickMenuInfo& info)
  178. {
  179. OP_NEW_DBG("OpScopeDesktopWindowManager::OnMenuShown()", "desktop-scope");
  180. OP_DBG(("Menu '%S' is %s", info.GetMenuId().GetMenuName().CStr(), shown?"SHOWN":"HIDDEN"));
  181. // Only send the message if scope is enabled
  182. if (!IsEnabled())
  183. return;
  184. if (shown)
  185. RETURN_VOID_IF_ERROR(SendOnMenuShown(info));
  186. else
  187. {
  188. RETURN_VOID_IF_ERROR(SendOnMenuClosed(info.GetMenuId()));
  189. }
  190. }
  191. ////////////////////////////////////////////////////////////////////////
  192. void OpScopeDesktopWindowManager::OnClose(WidgetWindow* window)
  193. {
  194. // Only send the message if scope is enabled
  195. if (!IsEnabled())
  196. return;
  197. DesktopWidgetWindow* widget_window = static_cast<DesktopWidgetWindow*>(window);
  198. #ifdef _DEBUG_SCOPE_TIMING2
  199. printf("OnWidgetWindowClose %s\n", widget_window->GetWindowName());
  200. #endif // _DEBUG_SCOPE_TIMING
  201. DesktopWindowInfo info;
  202. RETURN_VOID_IF_ERROR(SetDesktopWindowInfo(info, widget_window));
  203. // Just send the same shown event until we decide to make a special event
  204. RETURN_VOID_IF_ERROR(SendOnWindowClosed(info));
  205. // Remove the closed window from the list
  206. OpStatus::Ignore(m_widget_windows.RemoveByItem(widget_window));
  207. }
  208. void OpScopeDesktopWindowManager::OnShow(WidgetWindow* window, BOOL shown)
  209. {
  210. // Only send the message if scope is enabled
  211. if (!IsEnabled())
  212. return;
  213. DesktopWidgetWindow* widget_window = static_cast<DesktopWidgetWindow*>(window);
  214. #ifdef _DEBUG_SCOPE_TIMING2
  215. printf("OnWidgetWindowShown %s, Show: %u\n", widget_window->GetWindowName(), shown);
  216. #endif // _DEBUG_SCOPE_TIMING
  217. DesktopWindowInfo info;
  218. RETURN_VOID_IF_ERROR(SetDesktopWindowInfo(info, widget_window));
  219. if (shown)
  220. {
  221. RETURN_VOID_IF_ERROR(SendOnWindowShown(info));
  222. if (m_widget_windows.Find(widget_window) == -1)
  223. OpStatus::Ignore(m_widget_windows.Add(widget_window));
  224. }
  225. else
  226. {
  227. // We should always remove items from the list as soon as we know they
  228. // are not longer visible
  229. OpStatus::Ignore(m_widget_windows.RemoveByItem(widget_window));
  230. }
  231. }
  232. ////////////////////////////////////////////////////////////////////////
  233. void OpScopeDesktopWindowManager::OnLoadingFinished(DocumentDesktopWindow* document_window, OpLoadingListener::LoadingFinishStatus status, BOOL was_stopped_by_user)
  234. {
  235. // Only send the message if scope is enabled
  236. if (!IsEnabled())
  237. return;
  238. /*LOADING_SUCCESS, LOADING_REDIRECT, LOADING_COULDNT_CONNECT, LOADING_UNKNOWN*/
  239. if (status == OpLoadingListener::LOADING_SUCCESS || status == OpLoadingListener::LOADING_COULDNT_CONNECT)
  240. {
  241. #ifdef _DEBUG_SCOPE_TIMING
  242. OpString url;
  243. document_window->GetURL(url);
  244. printf("OnLoadingFinished %s\n", url.UTF8AllocL());
  245. #endif //_DEBUG_SCOPE_TIMING
  246. PageLoaded(document_window);
  247. }
  248. }
  249. void OpScopeDesktopWindowManager::PageLoaded(DesktopWindow* desktop_window)
  250. {
  251. // Only send the message if scope is enabled
  252. if (!IsEnabled())
  253. return;
  254. // Build and send the scope event
  255. DesktopWindowInfo info;
  256. RETURN_VOID_IF_ERROR(SetDesktopWindowInfo(info, desktop_window));
  257. RETURN_VOID_IF_ERROR(SendOnWindowPageLoaded(info));
  258. }
  259. ////////////////////////////////////////////////////////////////////////
  260. void OpScopeDesktopWindowManager::CopyDesktopWindowInfo(DesktopWindowInfo &from, DesktopWindowInfo &to)
  261. {
  262. to.ResetEncodedSize();
  263. to.GetRectRef().ResetEncodedSize();
  264. // Copy over the data. This is her as the DesktopWindowInfo is generated code
  265. to.SetWindowID(from.GetWindowID());
  266. to.SetTitle(from.GetTitle());
  267. to.SetName(from.GetName());
  268. to.SetWindowType(from.GetWindowType());
  269. to.SetOnScreen(from.GetOnScreen());
  270. to.SetState(from.GetState());
  271. to.GetRectRef().SetX(from.GetRect().GetX());
  272. to.GetRectRef().SetY(from.GetRect().GetY());
  273. to.GetRectRef().SetWidth(from.GetRect().GetWidth());
  274. to.GetRectRef().SetHeight(from.GetRect().GetHeight());
  275. }
  276. ////////////////////////////////////////////////////////////////////////
  277. OpScopeDesktopWindowManager_SI::DesktopWindowInfo::DesktopWindowType OpScopeDesktopWindowManager::GetWindowType(OpTypedObject::Type type)
  278. {
  279. if (type >= OpTypedObject::DIALOG_TYPE && type < OpTypedObject::DIALOG_TYPE_LAST)
  280. return DesktopWindowInfo::DESKTOPWINDOWTYPE_DIALOG;
  281. switch (type)
  282. {
  283. case OpTypedObject::WINDOW_TYPE_UNKNOWN:
  284. return DesktopWindowInfo::DESKTOPWINDOWTYPE_UNKNOWN;
  285. case OpTypedObject::WINDOW_TYPE_DESKTOP:
  286. case OpTypedObject::WINDOW_TYPE_DESKTOP_WITH_BROWSER_VIEW:
  287. case OpTypedObject::WINDOW_TYPE_BROWSER:
  288. case OpTypedObject::WINDOW_TYPE_MAIL_VIEW:
  289. case OpTypedObject::WINDOW_TYPE_MAIL_COMPOSE:
  290. case OpTypedObject::WINDOW_TYPE_HOTLIST:
  291. case OpTypedObject::WINDOW_TYPE_DOCUMENT:
  292. case OpTypedObject::WINDOW_TYPE_CHAT:
  293. case OpTypedObject::WINDOW_TYPE_CHAT_ROOM:
  294. case OpTypedObject::WINDOW_TYPE_HELP:
  295. case OpTypedObject::WINDOW_TYPE_UI_BUILDER:
  296. case OpTypedObject::WINDOW_TYPE_JAVASCRIPT_CONSOLE:
  297. case OpTypedObject::WINDOW_TYPE_PAGE_CYCLER:
  298. case OpTypedObject::WINDOW_TYPE_PANEL:
  299. #ifdef CDK_MODE_SUPPORT
  300. case OpTypedObject::WINDOW_TYPE_EMULATOR:
  301. #endif //CDK_MODE_SUPPORT
  302. case OpTypedObject::WINDOW_TYPE_SOURCE:
  303. case OpTypedObject::WINDOW_TYPE_GADGET:
  304. case OpTypedObject::WINDOW_TYPE_ACCESSKEY_CYCLER:
  305. case OpTypedObject::WINDOW_TYPE_DEVTOOLS:
  306. // Desktop specific:
  307. case OpTypedObject::WINDOW_TYPE_TOOLTIP:
  308. case OpTypedObject::WINDOW_TYPE_TOPLEVEL:
  309. case OpTypedObject::WIDGET_TYPE_WIDGETWINDOW:
  310. return DesktopWindowInfo::DESKTOPWINDOWTYPE_NORMAL;
  311. default:
  312. OP_ASSERT(!"Add new Window Type to the above list!");
  313. break;
  314. }
  315. return DesktopWindowInfo::DESKTOPWINDOWTYPE_UNKNOWN;
  316. }
  317. ////////////////////////////////////////////////////////////////////////
  318. OpScopeDesktopWindowManager_SI::DesktopWindowInfo::DesktopWindowState OpScopeDesktopWindowManager::GetWindowState(OpWindow::State state)
  319. {
  320. switch (state)
  321. {
  322. case OpWindow::RESTORED:
  323. return DesktopWindowInfo::DESKTOPWINDOWSTATE_RESTORED;
  324. case OpWindow::MAXIMIZED:
  325. return DesktopWindowInfo::DESKTOPWINDOWSTATE_MAXIMIZED;
  326. case OpWindow::MINIMIZED:
  327. return DesktopWindowInfo::DESKTOPWINDOWSTATE_MINIMIZED;
  328. case OpWindow::FULLSCREEN:
  329. return DesktopWindowInfo::DESKTOPWINDOWSTATE_FULLSCREEN;
  330. default:
  331. OP_ASSERT(!"Add new Window State to the above list!");
  332. break;
  333. }
  334. return DesktopWindowInfo::DESKTOPWINDOWSTATE_RESTORED;
  335. }
  336. ////////////////////////////////////////////////////////////////////////
  337. OP_STATUS OpScopeDesktopWindowManager::SetDesktopWindowInfo(DesktopWindowInfo &info, DesktopWidgetWindow *win)
  338. {
  339. info.SetWindowID(win->GetID());
  340. RETURN_IF_ERROR(info.SetTitle(win->GetTitle()));
  341. {
  342. OpString win_name;
  343. RETURN_IF_ERROR(win_name.Set(win->GetWindowName()));
  344. RETURN_IF_ERROR(info.SetName(win_name.CStr()));
  345. }
  346. info.SetWindowType(GetWindowType(win->GetType()));
  347. // // Set the rect
  348. INT32 x = 0;
  349. INT32 y = 0;
  350. UINT32 w = 0;
  351. UINT32 h = 0;
  352. if (win->GetWindow())
  353. {
  354. win->GetWindow()->GetOuterSize(&w, &h);
  355. win->GetWindow()->GetOuterPos(&x, &y);
  356. }
  357. info.GetRectRef().SetX(x);
  358. info.GetRectRef().SetY(y);
  359. info.GetRectRef().SetWidth(w);
  360. info.GetRectRef().SetHeight(h);
  361. // // TODO: FIXME: Figure out if the window is on the screen
  362. // OpScreenProperties screen_props;
  363. // g_op_screen_info->GetProperties(&screen_props, win->GetWindow(), NULL);
  364. // Set the onscreen flag
  365. info.SetOnScreen(true);
  366. // Set the window state
  367. OpRect rect_dummy;
  368. OpWindow::State state = OpWindow::RESTORED;
  369. if (win->GetWindow())
  370. win->GetWindow()->GetDesktopPlacement(rect_dummy, state);
  371. info.SetState(GetWindowState(state));
  372. info.SetActive(FALSE);
  373. return OpStatus::OK;
  374. }
  375. ////////////////////////////////////////////////////////////////////////
  376. OP_STATUS OpScopeDesktopWindowManager::SetDesktopWindowInfo(DesktopWindowInfo &info, DesktopWindow *win)
  377. {
  378. info.SetWindowID(win->GetID());
  379. RETURN_IF_ERROR(info.SetTitle(win->GetTitle()));
  380. {
  381. OpString win_name;
  382. RETURN_IF_ERROR(win_name.Set(win->GetSpecificWindowName()));
  383. RETURN_IF_ERROR(info.SetName(win_name.CStr()));
  384. }
  385. info.SetWindowType(GetWindowType(win->GetType()));
  386. // Set the rect
  387. OpRect rect;
  388. win->GetAbsoluteRect(rect);
  389. info.GetRectRef().SetX(rect.x);
  390. info.GetRectRef().SetY(rect.y);
  391. info.GetRectRef().SetWidth(rect.width);
  392. info.GetRectRef().SetHeight(rect.height);
  393. // Figure out if the window is on the screen
  394. OpScreenProperties screen_props;
  395. g_op_screen_info->GetProperties(&screen_props, win->GetWindow(), NULL);
  396. // Set the onscreen flag
  397. info.SetOnScreen(screen_props.screen_rect.Contains(rect));
  398. // Set the window state
  399. OpRect rect_dummy;
  400. OpWindow::State state;
  401. win->GetOpWindow()->GetDesktopPlacement(rect_dummy, state);
  402. info.SetState(GetWindowState(state));
  403. info.SetActive(win->IsActive());
  404. return OpStatus::OK;
  405. }
  406. /* virtual */ OP_STATUS
  407. OpScopeDesktopWindowManager::OnServiceEnabled()
  408. {
  409. // Kill any Widget Windows tracked in the previous session
  410. m_widget_windows.Clear();
  411. return OpStatus::OK;
  412. }
  413. ////////////////////////////////////////////////////////////////////////
  414. OpScopeDesktopWindowManager_SI::QuickWidgetInfo::QuickWidgetType OpScopeDesktopWindowManager::GetWidgetType(OpWidget *widget)
  415. {
  416. OpTypedObject::Type type = widget->GetType();
  417. switch (type)
  418. {
  419. case OpTypedObject::WIDGET_TYPE_BUTTON:
  420. {
  421. OpButton* button = static_cast<OpButton*>(widget);
  422. if (button->GetPropertyPage())
  423. return QuickWidgetInfo::QUICKWIDGETTYPE_DIALOGTAB;
  424. // fall through
  425. }
  426. case OpTypedObject::WIDGET_TYPE_EXPAND:
  427. case OpTypedObject::WIDGET_TYPE_NEW_PAGE_BUTTON:
  428. case OpTypedObject::WIDGET_TYPE_STATE_BUTTON:
  429. case OpTypedObject::WIDGET_TYPE_ZOOM_MENU_BUTTON:
  430. case OpTypedObject::WIDGET_TYPE_PAGEBAR_BUTTON:
  431. case OpTypedObject::WIDGET_TYPE_TRUST_AND_SECURITY_BUTTON:
  432. case OpTypedObject::WIDGET_TYPE_TOOLBAR_MENU_BUTTON:
  433. case OpTypedObject::WIDGET_TYPE_SHRINK_ANIMATION:
  434. case OpTypedObject::WIDGET_TYPE_HOTLIST_CONFIG_BUTTON:
  435. case OpTypedObject::WIDGET_TYPE_EXTENSION_BUTTON:
  436. case OpTypedObject::WIDGET_TYPE_TRASH_BIN_BUTTON:
  437. {
  438. if (widget->IsOfType(OpTypedObject::WIDGET_TYPE_PAGEBAR_BUTTON))
  439. return QuickWidgetInfo::QUICKWIDGETTYPE_TABBUTTON;
  440. else
  441. return QuickWidgetInfo::QUICKWIDGETTYPE_BUTTON;
  442. }
  443. case OpTypedObject::WIDGET_TYPE_CHECKBOX:
  444. return QuickWidgetInfo::QUICKWIDGETTYPE_CHECKBOX;
  445. case OpTypedObject::WIDGET_TYPE_GROUP:
  446. {
  447. // Dialog tabs have this GetTab set even though they are really a group
  448. if (static_cast<OpGroup *>(widget)->GetTab())
  449. return QuickWidgetInfo::QUICKWIDGETTYPE_DIALOGTAB;
  450. break;
  451. }
  452. case OpTypedObject::WIDGET_TYPE_DROPDOWN_WITHOUT_EDITBOX:
  453. case OpTypedObject::WIDGET_TYPE_DROPDOWN:
  454. return QuickWidgetInfo::QUICKWIDGETTYPE_DROPDOWN;
  455. case OpTypedObject::WIDGET_TYPE_EDIT:
  456. case OpTypedObject::WIDGET_TYPE_MULTILINE_EDIT:
  457. case OpTypedObject::WIDGET_TYPE_SEARCH_EDIT:
  458. case OpTypedObject::WIDGET_TYPE_COMPOSE_EDIT:
  459. case OpTypedObject::WIDGET_TYPE_RICH_TEXT_EDITOR:
  460. case OpTypedObject::WIDGET_TYPE_BROWSERVIEW: //TODO move to a separate type
  461. return QuickWidgetInfo::QUICKWIDGETTYPE_EDITFIELD;
  462. case OpTypedObject::WIDGET_TYPE_LABEL:
  463. case OpTypedObject::WIDGET_TYPE_RICHTEXT_LABEL:
  464. case OpTypedObject::WIDGET_TYPE_STATUS_FIELD:
  465. case OpTypedObject::WIDGET_TYPE_PASSWORD_STRENGTH:
  466. case OpTypedObject::WIDGET_TYPE_DESKTOP_LABEL:
  467. return QuickWidgetInfo::QUICKWIDGETTYPE_LABEL;
  468. case OpTypedObject::WIDGET_TYPE_RADIOBUTTON:
  469. return QuickWidgetInfo::QUICKWIDGETTYPE_RADIOBUTTON;
  470. case OpTypedObject::WIDGET_TYPE_SEARCH_DROPDOWN:
  471. case OpTypedObject::WIDGET_TYPE_RESIZE_SEARCH_DROPDOWN:
  472. case OpTypedObject::WIDGET_TYPE_SPEEDDIAL_SEARCH:
  473. return QuickWidgetInfo::QUICKWIDGETTYPE_SEARCH;
  474. case OpTypedObject::WIDGET_TYPE_ADDRESS_DROPDOWN:
  475. return QuickWidgetInfo::QUICKWIDGETTYPE_ADDRESSFIELD;
  476. case OpTypedObject::WIDGET_TYPE_TOOLBAR:
  477. case OpTypedObject::WIDGET_TYPE_PAGEBAR:
  478. case OpTypedObject::WIDGET_TYPE_PERSONALBAR:
  479. case OpTypedObject::WIDGET_TYPE_PERSONALBAR_INLINE:
  480. case OpTypedObject::WIDGET_TYPE_PANEL_SELECTOR:
  481. case OpTypedObject::WIDGET_TYPE_INFOBAR:
  482. case OpTypedObject::WIDGET_TYPE_FINDTEXTBAR:
  483. return QuickWidgetInfo::QUICKWIDGETTYPE_TOOLBAR;
  484. case OpTypedObject::WIDGET_TYPE_TREEVIEW:
  485. //case OpTypedObject::WIDGET_TYPE_LISTBOX:
  486. return QuickWidgetInfo::QUICKWIDGETTYPE_TREEVIEW;
  487. case OpTypedObject::WIDGET_TYPE_THUMBNAIL:
  488. return QuickWidgetInfo::QUICKWIDGETTYPE_THUMBNAIL;
  489. case OpTypedObject::WIDGET_TYPE_FLOW_LAYOUT:
  490. case OpTypedObject::WIDGET_TYPE_DYNAMIC_GRID_LAYOUT:
  491. return QuickWidgetInfo::QUICKWIDGETTYPE_GRIDLAYOUT;
  492. case OpTypedObject::WIDGET_TYPE_FLOW_LAYOUT_ITEM:
  493. case OpTypedObject::WIDGET_TYPE_DYNAMIC_GRID_ITEM:
  494. return QuickWidgetInfo:: QUICKWIDGETTYPE_GRIDITEM;
  495. case OpTypedObject::WIDGET_TYPE_QUICK_FIND:
  496. return QuickWidgetInfo::QUICKWIDGETTYPE_QUICKFIND;
  497. case OpTypedObject::WIDGET_TYPE_ICON:
  498. return QuickWidgetInfo::QUICKWIDGETTYPE_ICON;
  499. case OpTypedObject::WIDGET_TYPE_PROGRESSBAR:
  500. return QuickWidgetInfo::QUICKWIDGETTYPE_PROGRESSBAR;
  501. case OpTypedObject::WIDGET_TYPE_LISTBOX:
  502. return QuickWidgetInfo::QUICKWIDGETTYPE_LISTBOX;
  503. default:
  504. break;
  505. }
  506. return QuickWidgetInfo::QUICKWIDGETTYPE_UNKNOWN;
  507. }
  508. ////////////////////////////////////////////////////////////////////////
  509. OP_STATUS OpScopeDesktopWindowManager::SetQuickWidgetInfo(QuickWidgetInfo& info, OpWidget* widget)
  510. {
  511. OpString name;
  512. RETURN_IF_ERROR(name.Set(widget->GetName()));
  513. RETURN_IF_ERROR(info.SetName(name));
  514. info.SetType(GetWidgetType(widget));
  515. BOOL visible = widget->IsVisible();
  516. // If this widget is visible check if all its parents are also visible
  517. if (visible)
  518. {
  519. OpWidget *parent_widget = widget;
  520. while ((parent_widget = parent_widget->GetParent()) != NULL)
  521. {
  522. visible = parent_widget->IsVisible();
  523. if (!visible)
  524. break;
  525. }
  526. }
  527. // Note: There are more toolbar types than this one, add if neccessary
  528. if (visible && (widget->GetType() == OpTypedObject::WIDGET_TYPE_TOOLBAR
  529. || widget->GetType() == OpTypedObject::WIDGET_TYPE_PAGEBAR
  530. || widget->GetType() == OpTypedObject::WIDGET_TYPE_PERSONALBAR
  531. || widget->GetType() == OpTypedObject::WIDGET_TYPE_PERSONALBAR_INLINE
  532. || widget->GetType() == OpTypedObject::WIDGET_TYPE_PANEL_SELECTOR
  533. || widget->GetType() == OpTypedObject::WIDGET_TYPE_INFOBAR
  534. || widget->GetType() == OpTypedObject::WIDGET_TYPE_FINDTEXTBAR))
  535. {
  536. visible = static_cast<OpToolbar*>(widget)->IsOn();
  537. }
  538. else if (visible && widget->IsOfType(OpTypedObject::WIDGET_TYPE_BUTTON))
  539. {
  540. OpGroup* page = static_cast<OpButton*>(widget)->GetPropertyPage();
  541. if (page != NULL)
  542. // Make the tab button of an inactive dialog tab invisible.
  543. // In QuickTabs, the contents of an inactive tab are detached from
  544. // the tree, hence the GetParent() check.
  545. visible = page->IsVisible() && page->GetParent() != NULL;
  546. }
  547. info.SetVisible(visible);
  548. if (widget->GetType() != OpTypedObject::WIDGET_TYPE_DROPDOWN)
  549. {
  550. info.SetValue(widget->GetValue());
  551. }
  552. else
  553. {
  554. info.SetValue(static_cast<OpDropDown*>(widget)->IsDroppedDown() ? 1 : 0);
  555. }
  556. info.SetEnabled(widget->IsEnabled());
  557. if (widget->IsEnabled() && (widget->GetType() == OpTypedObject::WIDGET_TYPE_TOOLBAR
  558. || widget->GetType() == OpTypedObject::WIDGET_TYPE_PAGEBAR
  559. || widget->GetType() == OpTypedObject::WIDGET_TYPE_PERSONALBAR
  560. || widget->GetType() == OpTypedObject::WIDGET_TYPE_PERSONALBAR_INLINE
  561. || widget->GetType() == OpTypedObject::WIDGET_TYPE_PANEL_SELECTOR
  562. || widget->GetType() == OpTypedObject::WIDGET_TYPE_INFOBAR
  563. || widget->GetType() == OpTypedObject::WIDGET_TYPE_FINDTEXTBAR))
  564. info.SetEnabled(static_cast<OpToolbar*>(widget)->IsOn());
  565. // These items are set based on the widget type
  566. // First set them to what is the major defaults
  567. OpString text;
  568. OpString visible_text;
  569. BOOL default_look = FALSE;
  570. BOOL focused_look = FALSE;
  571. OpStatus::Ignore(widget->GetText(text));
  572. // Set visible text to same as text for all widgets except addressfield
  573. if (widget->GetType() != OpTypedObject::WIDGET_TYPE_ADDRESS_DROPDOWN)
  574. {
  575. info.SetVisible_text(text);
  576. info.SetAdditional_text(0);
  577. }
  578. if (widget->GetType() == OpTypedObject::WIDGET_TYPE_BROWSERVIEW)
  579. {
  580. text.Set(static_cast<OpBrowserView*>(widget)->GetWindowCommander()->GetSelectedText());
  581. }
  582. if (widget->GetType() == OpTypedObject::WIDGET_TYPE_THUMBNAIL && text.IsEmpty())
  583. {
  584. OpStatus::Ignore(text.Set(static_cast<GenericThumbnail*>(widget)->GetTitle()));
  585. }
  586. if (widget->GetType() == OpTypedObject::WIDGET_TYPE_RICH_TEXT_EDITOR)
  587. {
  588. RichTextEditor* rich_text_editor = static_cast<RichTextEditor*> (widget);
  589. if (OpStatus::IsSuccess(rich_text_editor->GetTextEquivalent(text)))
  590. info.SetVisible_text(text);
  591. OpString html_source;
  592. if (OpStatus::IsSuccess(rich_text_editor->GetHTMLSource(html_source)))
  593. info.SetAdditional_text(html_source);
  594. info.SetValue(rich_text_editor->IsHTML() ? 1 : 0);
  595. }
  596. // Set the specifics based on the widget type
  597. switch (widget->GetType())
  598. {
  599. // TODO: FIXME Which ones here?
  600. case OpTypedObject::WIDGET_TYPE_RADIOBUTTON:
  601. case OpTypedObject::WIDGET_TYPE_CHECKBOX:
  602. case OpTypedObject::WIDGET_TYPE_BUTTON:
  603. case OpTypedObject::WIDGET_TYPE_EXPAND:
  604. // case OpTypedObject::WIDGET_TYPE_NEW_PAGE_BUTTON:
  605. case OpTypedObject::WIDGET_TYPE_STATE_BUTTON:
  606. case OpTypedObject::WIDGET_TYPE_ZOOM_MENU_BUTTON:
  607. // case OpTypedObject::WIDGET_TYPE_PAGEBAR_BUTTON:
  608. // case OpTypedObject::WIDGET_TYPE_TRUST_AND_SECURITY_BUTTON:
  609. // case OpTypedObject::WIDGET_TYPE_TOOLBAR_MENU_BUTTON:
  610. case OpTypedObject::WIDGET_TYPE_SHRINK_ANIMATION:
  611. case OpTypedObject::WIDGET_TYPE_HOTLIST_CONFIG_BUTTON:
  612. case OpTypedObject::WIDGET_TYPE_EXTENSION_BUTTON:
  613. {
  614. // These are only relevant for Buttons
  615. default_look = static_cast<OpButton *>(widget)->HasDefaultLook();
  616. focused_look = static_cast<OpButton *>(widget)->HasForcedFocusedLook();
  617. }
  618. break;
  619. case OpTypedObject::WIDGET_TYPE_ADDRESS_DROPDOWN:
  620. {
  621. // The new address field is sometimes cut off so we'll get all of it!
  622. OpStatus::Ignore(static_cast<OpAddressDropDown *>(widget)->GetFullAddress(text));
  623. // The visible text
  624. static_cast<OpAddressDropDown *>(widget)->GetShowAddress(visible_text);
  625. info.SetVisible_text(visible_text);
  626. // The highlighted thext
  627. OpString additional_text;
  628. static_cast<OpAddressDropDown *>(widget)->GetHighlightDomain(additional_text);
  629. info.SetAdditional_text(additional_text);
  630. }
  631. break;
  632. case OpTypedObject::WIDGET_TYPE_DROPDOWN:
  633. case OpTypedObject::WIDGET_TYPE_DROPDOWN_WITHOUT_EDITBOX:
  634. {
  635. // Drop downs need to get the text of the selected item
  636. INT32 idx = static_cast<OpDropDown *>(widget)->GetSelectedItem();
  637. if (text.IsEmpty())
  638. RETURN_IF_ERROR(text.Set(static_cast<OpDropDown *>(widget)->GetItemText(idx)));
  639. }
  640. break;
  641. case OpTypedObject::WIDGET_TYPE_THUMBNAIL:
  642. info.SetCol(MAX(static_cast<GenericThumbnail*>(widget)->GetNumber(), 0));
  643. break;
  644. default:
  645. break;
  646. }
  647. // Set the items we set above based on the widget type
  648. info.SetDefaultLook(default_look);
  649. info.SetFocusedLook(focused_look);
  650. info.SetText(text);
  651. OpRect rect;
  652. // Add hacks for widgets within widgets like tabs on dialogs
  653. // which are just buttons on groups
  654. switch (widget->GetType())
  655. {
  656. case OpTypedObject::WIDGET_TYPE_GROUP:
  657. {
  658. OpButton *tab = static_cast<OpGroup *>(widget)->GetTab();
  659. if (tab)
  660. rect = tab->GetScreenRect();
  661. else
  662. rect = widget->GetScreenRect();
  663. break;
  664. }
  665. default:
  666. rect = widget->GetScreenRect();
  667. break;
  668. }
  669. // Set Column on tab buttons
  670. if (widget->IsOfType(OpTypedObject::WIDGET_TYPE_PAGEBAR_BUTTON))
  671. {
  672. // Set position
  673. OpWidget* parent = GetParentToolbar(widget);
  674. if (parent && parent->GetType() == OpTypedObject::WIDGET_TYPE_PAGEBAR)
  675. {
  676. PagebarButton *button = static_cast<PagebarButton *>(widget);
  677. INT32 pos = static_cast<OpPagebar*>(parent)->GetPosition(button);
  678. info.SetCol(pos);
  679. info.SetRow(0);
  680. }
  681. if (widget->GetName().IsEmpty() || widget->GetName().Find("Tab ") == 0)
  682. {
  683. // Set Name based on position
  684. OpString name;
  685. name.AppendFormat("Tab %d", info.GetCol());
  686. info.SetName(name);
  687. // SetName on the parent
  688. OpString8 name8;
  689. name8.Set(name);
  690. widget->SetName(name8);
  691. }
  692. }
  693. // Set parent ---------
  694. OpWidget* parent = widget->GetParent();
  695. if (parent)
  696. {
  697. // Set position for buttons in Bookmarks bar
  698. if (parent->GetType() == OpTypedObject::WIDGET_TYPE_PERSONALBAR_INLINE)
  699. {
  700. INT32 position = static_cast<OpPersonalbar *>(parent)->GetPosition(widget);
  701. if (position != -1)
  702. info.SetCol(position);
  703. info.SetRow(0);
  704. }
  705. if (parent->GetType() == OpTypedObject::WIDGET_TYPE_SEARCH_SPECIAL_DROPDOWN || // It doesn't have a name
  706. parent->GetType() == OpTypedObject::WIDGET_TYPE_EXTENSION_SET || // This type is unknown for watir
  707. parent->GetType() == OpTypedObject::WIDGET_TYPE_COMPOSITE) // Always skip Composite
  708. {
  709. parent = parent->GetParent();
  710. }
  711. }
  712. else
  713. {
  714. // Widgets that must have their parent set:
  715. // Controls in toolbars, pagebar and personalbar
  716. // Controls within tab buttons
  717. // FIXME: This needs to be generalized
  718. parent = GetParentTab(widget); // Pagebar buttons
  719. if (!parent) // If parent not already set
  720. {
  721. // if ancestor is a toolbar, pagebar, personalbar, setParentName(toolbarname)
  722. parent = GetParentToolbar(widget);
  723. }
  724. }
  725. if (parent && parent->GetName().HasContent())
  726. {
  727. OpString parent_name;
  728. RETURN_IF_ERROR(parent_name.Set(parent->GetName()));
  729. info.SetParent(parent_name);
  730. }
  731. // Set the rect
  732. info.GetRectRef().SetX(rect.x);
  733. info.GetRectRef().SetY(rect.y);
  734. info.GetRectRef().SetWidth(rect.width);
  735. info.GetRectRef().SetHeight(rect.height);
  736. return OpStatus::OK;
  737. }
  738. ////////////////////////////////////////////////////////////////////////
  739. /**
  740. *
  741. * For Controls inside a tabbutton, we set the parent of the control to be the tabbutton
  742. * GetParentTab returns the tabbutton parent of a widget, if any
  743. *
  744. */
  745. OpWidget* OpScopeDesktopWindowManager::GetParentTab(OpWidget* widget)
  746. {
  747. OpWidget* wdg = 0;
  748. if (widget)
  749. {
  750. if (widget->IsOfType(OpTypedObject::WIDGET_TYPE_PAGEBAR_BUTTON))
  751. {
  752. return 0;
  753. }
  754. wdg = widget->GetParent();
  755. }
  756. // Currently only checking immediate parent
  757. /*while (wdg && !wdg->IsOfType(OpTypedObject::WIDGET_TYPE_PAGEBAR_BUTTON))
  758. {
  759. wdg = wdg->GetParent();
  760. }*/
  761. if (wdg && wdg->IsOfType(OpTypedObject::WIDGET_TYPE_PAGEBAR_BUTTON))
  762. return wdg;
  763. else
  764. return 0;
  765. }
  766. ////////////////////////////////////////////////////////////////////////
  767. // TODO paremeterize on type (GetParentWidget(widget, Type))
  768. /**
  769. * returns the toolbar that is a parent (ancestor) of widget, if any
  770. *
  771. *
  772. */
  773. OpWidget* OpScopeDesktopWindowManager::GetParentToolbar(OpWidget* widget)
  774. {
  775. OpWidget* wdg = 0;
  776. if (widget)
  777. {
  778. if (widget->GetType() == OpTypedObject::WIDGET_TYPE_TOOLBAR
  779. || widget->GetType() == OpTypedObject::WIDGET_TYPE_PAGEBAR
  780. || widget->GetType() == OpTypedObject::WIDGET_TYPE_PERSONALBAR
  781. || widget->GetType() == OpTypedObject::WIDGET_TYPE_PERSONALBAR_INLINE
  782. || widget->GetType() == OpTypedObject::WIDGET_TYPE_PANEL_SELECTOR
  783. || widget->GetType() == OpTypedObject::WIDGET_TYPE_INFOBAR
  784. || widget->GetType() == OpTypedObject::WIDGET_TYPE_FINDTEXTBAR)
  785. {
  786. return 0;
  787. }
  788. wdg = widget->GetParent();
  789. }
  790. while (wdg && wdg->GetType() != OpTypedObject::WIDGET_TYPE_TOOLBAR
  791. && wdg->GetType() != OpTypedObject::WIDGET_TYPE_PAGEBAR
  792. && wdg->GetType() != OpTypedObject::WIDGET_TYPE_PERSONALBAR
  793. && wdg->GetType() != OpTypedObject::WIDGET_TYPE_PERSONALBAR_INLINE
  794. && wdg->GetType() != OpTypedObject::WIDGET_TYPE_PANEL_SELECTOR
  795. && wdg->GetType() != OpTypedObject::WIDGET_TYPE_INFOBAR
  796. && wdg->GetType() != OpTypedObject::WIDGET_TYPE_FINDTEXTBAR)
  797. {
  798. wdg = wdg->GetParent();
  799. }
  800. return wdg;
  801. }
  802. ////////////////////////////////////////////////////////////////////////
  803. /**
  804. * Build access string which can be used to specify the widget to desktop-watir
  805. * e.g. [browser.quick_window(:name, "name").]quick_button(:name, "name")
  806. *
  807. * BuildWatirAccessString appends (or if insert_first TRUE, inserts) one widget in the string access_path
  808. * @param widget_info - the widget info for the widget whose access specifier is to be inserted/appended
  809. * @param access_path - the (partial) path to append or insert this widget access part into
  810. *
  811. */
  812. void OpScopeDesktopWindowManager::BuildWatirAccessString(QuickWidgetInfo& widget_info, OpString& access_path, BOOL insert_first)
  813. {
  814. OpString access_string;
  815. GetWatirWidgetType(widget_info.GetType(), access_string);
  816. if (widget_info.GetType() == QuickWidgetInfo::QUICKWIDGETTYPE_TREEITEM && widget_info.GetText().HasContent())
  817. {
  818. access_string.AppendFormat("(:string_id, LookupStringId(%s))", widget_info.GetText().CStr());
  819. }
  820. else if (widget_info.GetType() == QuickWidgetInfo::QUICKWIDGETTYPE_TREEITEM)
  821. {
  822. access_string.AppendFormat("(:pos, [%u, %u])", widget_info.GetRow(), widget_info.GetCol());
  823. }
  824. // If button in personalbar use pos
  825. else if (widget_info.GetType() == QuickWidgetInfo::QUICKWIDGETTYPE_BUTTON &&
  826. widget_info.GetParent().Compare("Personalbar Inline") == 0
  827. || widget_info.GetType() == QuickWidgetInfo::QUICKWIDGETTYPE_THUMBNAIL &&
  828. widget_info.GetName().IsEmpty())
  829. {
  830. access_string.AppendFormat(UNI_L("(:pos, %u)"), widget_info.GetCol());
  831. }
  832. // Use name if possible
  833. else if (widget_info.GetName().HasContent())
  834. {
  835. access_string.AppendFormat("(:name, \"%s\")", widget_info.GetName().CStr());
  836. }
  837. else if (widget_info.GetText().HasContent())
  838. {
  839. // Tabs don't have a name
  840. access_string.AppendFormat(widget_info.GetType() == QuickWidgetInfo::QUICKWIDGETTYPE_TABBUTTON ?
  841. "(:text, \"%s\")" : "(:string_id, LookupStringId(%s))", widget_info.GetText().CStr());
  842. }
  843. else
  844. {
  845. access_string.Append("([Unnamed])");
  846. }
  847. // Wrap
  848. if (access_string.Length() > 25)
  849. access_string.Append("\n\t");
  850. if (insert_first)
  851. {
  852. access_string.Insert(0, ".");
  853. access_path.Insert(0, access_string);
  854. }
  855. else
  856. {
  857. access_path.Append(".");
  858. access_path.Append(access_string);
  859. }
  860. }
  861. ////////////////////////////////////////////////////////////////////////
  862. void OpScopeDesktopWindowManager::GetWatirWidgetType(QuickWidgetInfo::QuickWidgetType type, OpString& widget_type)
  863. {
  864. const char *type_str = NULL;
  865. switch (type)
  866. {
  867. case QuickWidgetInfo::QUICKWIDGETTYPE_BUTTON:
  868. type_str = "quick_button";
  869. break;
  870. case QuickWidgetInfo::QUICKWIDGETTYPE_CHECKBOX:
  871. type_str = "quick_checkbox";
  872. break;
  873. case QuickWidgetInfo::QUICKWIDGETTYPE_DIALOGTAB:
  874. type_str = "quick_dialogtab";
  875. break;
  876. case QuickWidgetInfo::QUICKWIDGETTYPE_DROPDOWN:
  877. type_str = "quick_dropdown";
  878. break;
  879. case QuickWidgetInfo::QUICKWIDGETTYPE_EDITFIELD:
  880. type_str = "quick_editfield";
  881. break;
  882. case QuickWidgetInfo::QUICKWIDGETTYPE_LABEL:
  883. type_str = "quick_label";
  884. break;
  885. case QuickWidgetInfo::QUICKWIDGETTYPE_RADIOBUTTON:
  886. type_str = "quick_radiobutton";
  887. break;
  888. case QuickWidgetInfo::QUICKWIDGETTYPE_ADDRESSFIELD:
  889. type_str = "quick_addressfield";
  890. break;
  891. case QuickWidgetInfo::QUICKWIDGETTYPE_SEARCH:
  892. type_str = "quick_searchfield";
  893. break;
  894. case QuickWidgetInfo::QUICKWIDGETTYPE_TOOLBAR:
  895. type_str = "quick_toolbar";
  896. break;
  897. case QuickWidgetInfo::QUICKWIDGETTYPE_TREEVIEW:
  898. type_str = "quick_treeview";
  899. break;
  900. case QuickWidgetInfo::QUICKWIDGETTYPE_TREEITEM:
  901. type_str = "quick_treeitem";
  902. break;
  903. case QuickWidgetInfo::QUICKWIDGETTYPE_TABBUTTON:
  904. type_str = "quick_tab";
  905. break;
  906. case QuickWidgetInfo::QUICKWIDGETTYPE_THUMBNAIL:
  907. type_str = "quick_thumbnail";
  908. break;
  909. case QuickWidgetInfo::QUICKWIDGETTYPE_GRIDLAYOUT:
  910. type_str = "quick_gridlayout";
  911. break;
  912. case QuickWidgetInfo::QUICKWIDGETTYPE_GRIDITEM:
  913. type_str = "quick_griditem";
  914. break;
  915. case QuickWidgetInfo::QUICKWIDGETTYPE_QUICKFIND:
  916. type_str = "quick_find";
  917. break;
  918. case QuickWidgetInfo::QUICKWIDGETTYPE_ICON:
  919. type_str = "quick_icon";
  920. break;
  921. case QuickWidgetInfo::QUICKWIDGETTYPE_PROGRESSBAR:
  922. type_str = "quick_progressbar";
  923. break;
  924. case QuickWidgetInfo::QUICKWIDGETTYPE_LISTBOX:
  925. type_str = "quick_listbox";
  926. break;
  927. //case QUICKWIDGETTYPE_UNKNOWN
  928. default:
  929. type_str = "quick_unknown";
  930. break;
  931. }
  932. if (type_str)
  933. OpStatus::Ignore(widget_type.Set(type_str));
  934. }
  935. ////////////////////////////////////////////////////////////////////////
  936. /**
  937. *
  938. * Appends widget information for the widget given by widget_info (and widget) to tooltip_text
  939. * and if add_to_path TRUE, adds accessor string for this widget (and parents) to watir_access_path
  940. *
  941. *
  942. */
  943. void OpScopeDesktopWindowManager::GetQuickWidgetInfoToolTip(QuickWidgetInfo &widget_info, OpString &tooltip_text, OpString &watir_access_path, BOOL add_to_path, BOOL next_parent, OpWidget *widget, BOOL skip_parents)
  944. {
  945. const char *type_str = NULL;
  946. switch (widget_info.GetType())
  947. {
  948. case QuickWidgetInfo::QUICKWIDGETTYPE_BUTTON:
  949. // Check if this is a dialog tab's button
  950. if (widget && static_cast<OpButton *>(widget)->GetButtonType() == OpButton::TYPE_TAB && static_cast<OpButton *>(widget)->GetPropertyPage())
  951. {
  952. // Get the name of the control from the Group since that's what you really want to access
  953. if (OpStatus::IsSuccess(SetQuickWidgetInfo(widget_info, static_cast<OpButton *>(widget)->GetPropertyPage())))
  954. {
  955. // TODO: FIXME: Not sure if check_parent should be set here or not
  956. GetQuickWidgetInfoToolTip(widget_info, tooltip_text, watir_access_path, TRUE, FALSE, static_cast<OpButton *>(widget)->GetPropertyPage());
  957. return;
  958. }
  959. }
  960. type_str = "Button";
  961. break;
  962. case QuickWidgetInfo::QUICKWIDGETTYPE_CHECKBOX:
  963. type_str = "Checkbox";
  964. break;
  965. case QuickWidgetInfo::QUICKWIDGETTYPE_DIALOGTAB:
  966. type_str = "Dialog Tab";
  967. break;
  968. case QuickWidgetInfo::QUICKWIDGETTYPE_DROPDOWN:
  969. type_str = "Drop Down";
  970. break;
  971. case QuickWidgetInfo::QUICKWIDGETTYPE_EDITFIELD:
  972. type_str = "Edit Field";
  973. break;
  974. case QuickWidgetInfo::QUICKWIDGETTYPE_LABEL:
  975. type_str = "Label";
  976. break;
  977. case QuickWidgetInfo::QUICKWIDGETTYPE_RADIOBUTTON:
  978. type_str = "Radio Button";
  979. break;
  980. case QuickWidgetInfo::QUICKWIDGETTYPE_ADDRESSFIELD:
  981. type_str = "Address Field";
  982. break;
  983. case QuickWidgetInfo::QUICKWIDGETTYPE_SEARCH:
  984. type_str = "Search Field";
  985. break;
  986. case QuickWidgetInfo::QUICKWIDGETTYPE_TOOLBAR:
  987. type_str = "Toolbar";
  988. break;
  989. case QuickWidgetInfo::QUICKWIDGETTYPE_TREEVIEW:
  990. type_str = "Treeview";
  991. break;
  992. case QuickWidgetInfo::QUICKWIDGETTYPE_TREEITEM:
  993. type_str = "Treeview Item";
  994. break;
  995. case QuickWidgetInfo::QUICKWIDGETTYPE_TABBUTTON:
  996. type_str = "Tab Button";
  997. break;
  998. case QuickWidgetInfo::QUICKWIDGETTYPE_THUMBNAIL:
  999. type_str = "Thumbnail";
  1000. break;
  1001. case QuickWidgetInfo::QUICKWIDGETTYPE_GRIDLAYOUT:
  1002. type_str = "GridLayout";
  1003. break;
  1004. case QuickWidgetInfo::QUICKWIDGETTYPE_GRIDITEM:
  1005. type_str = "GridItem";
  1006. break;
  1007. case QuickWidgetInfo::QUICKWIDGETTYPE_LISTBOX:
  1008. type_str = "Listbox";
  1009. break;
  1010. case QuickWidgetInfo::QUICKWIDGETTYPE_QUICKFIND:
  1011. type_str = "QuickFind";
  1012. break;
  1013. case QuickWidgetInfo::QUICKWIDGETTYPE_ICON:
  1014. type_str = "QuickIcon";
  1015. break;
  1016. case QuickWidgetInfo::QUICKWIDGETTYPE_PROGRESSBAR:
  1017. type_str = "QuickProgressBar";
  1018. break;
  1019. }
  1020. OpString widget_type;
  1021. if (type_str)
  1022. {
  1023. OpStatus::Ignore(widget_type.Set(type_str));
  1024. }
  1025. else
  1026. {
  1027. OpStatus::Ignore(widget_type.Set("Unknown"));
  1028. // Append the number of the OpWidget Type so we have an idea on what we have missed
  1029. if (widget)
  1030. widget_type.AppendFormat(" %u", widget->GetType());
  1031. }
  1032. // Space out the entries
  1033. if (tooltip_text.HasContent())
  1034. tooltip_text.Append("\n");
  1035. tooltip_text.AppendFormat("Quick Widget Information:\n----------------------\n"
  1036. "Name: %s\n"
  1037. "Text: %s\n"
  1038. "Visible text: %s\n"
  1039. "%s text: %s\n"
  1040. "Type: %s\n"
  1041. "Parent: %s\n"
  1042. "Value: =%u\n"
  1043. "Visible: %s\n"
  1044. "Enabled: %s\n"
  1045. "Pos: x=%u, y=%u\n"
  1046. "Size: width=%u, height=%u\n"
  1047. "Ref: row=%u, col=%u\n",
  1048. widget_info.GetName().HasContent() ? widget_info.GetName().CStr() : UNI_L("[unnamed]"),
  1049. widget_info.GetText().HasContent() ? widget_info.GetText().CStr() : UNI_L("[no text]"),
  1050. widget_info.GetVisible_text().HasContent() ? widget_info.GetVisible_text().CStr() : UNI_L("[no text]"),
  1051. widget_info.GetType() == QuickWidgetInfo::QUICKWIDGETTYPE_ADDRESSFIELD ? UNI_L("Highlighted") : UNI_L("Additional"),
  1052. widget_info.GetAdditional_text().HasContent() ? widget_info.GetAdditional_text().CStr() : UNI_L("[no text]"),
  1053. widget_type.CStr(),
  1054. widget_info.GetParent().HasContent() ? widget_info.GetParent().CStr() : UNI_L("[no parent]"),
  1055. widget_info.GetValue(),
  1056. widget_info.GetVisible() ? UNI_L("Yes") : UNI_L("No"),
  1057. widget_info.GetEnabled() ? UNI_L("Yes") : UNI_L("No"),
  1058. widget_info.GetRect().GetX(), widget_info.GetRect().GetY(),
  1059. widget_info.GetRect().GetWidth(), widget_info.GetRect().GetHeight(),
  1060. widget_info.GetRow(), widget_info.GetCol());
  1061. // Add all the parent widgets
  1062. if (widget && !skip_parents)
  1063. {
  1064. OpWidget *parent_widget = widget;
  1065. OpString parent_name;
  1066. parent_name.Set(widget_info.GetParent());
  1067. BOOL next_parent = FALSE;
  1068. while ((parent_widget = parent_widget->GetParent()) != NULL)
  1069. {
  1070. QuickWidgetInfo parent_info;
  1071. if (OpStatus::IsSuccess(SetQuickWidgetInfo(parent_info, parent_widget)))
  1072. {
  1073. // If we have hit an unknown widget we have gone far enough
  1074. if (parent_info.GetType() != QuickWidgetInfo::QUICKWIDGETTYPE_UNKNOWN)
  1075. {
  1076. // If you get here, meaning you will print the parent, say you want to print it to access path only if it's set
  1077. // as my parent
  1078. BOOL add_parent_to_path = FALSE;
  1079. if (parent_info.GetName().HasContent() && parent_name.Compare(parent_info.GetName()) == 0
  1080. || parent_info.GetText().HasContent() && parent_name.Compare(parent_info.GetText()) == 0)
  1081. {
  1082. add_parent_to_path = TRUE;
  1083. }
  1084. GetQuickWidgetInfoToolTip(parent_info, tooltip_text, watir_access_path, add_parent_to_path, next_parent, parent_widget, /* skip_parents */TRUE);
  1085. if (add_parent_to_path)
  1086. next_parent = TRUE;
  1087. // If the parent was set as my parent and was added to path, then reset parent_name to be my parent's parent
  1088. if (add_parent_to_path)
  1089. parent_name.Set(parent_info.GetParent());
  1090. }
  1091. }
  1092. }
  1093. }
  1094. // TODO: Add Text for some widgets instead
  1095. if (add_to_path)
  1096. {
  1097. // Here set the watir_access_path for this widget
  1098. // If this is a 'next_parent' then insert_first, else append
  1099. BuildWatirAccessString(widget_info, watir_access_path, next_parent /* insert_first*/);
  1100. }
  1101. }
  1102. ////////////////////////////////////////////////////////////////////////
  1103. void OpScopeDesktopWindowManager::GetQuickWidgetInfoToolTip(OpWidget *widget, OpString &tooltip_text)
  1104. {
  1105. OpString watir_access_path;
  1106. OpString subitem_access;
  1107. // First check if this widget needs to be broken down into QuickWidgetInfo items
  1108. OpAutoPtr<OpScopeWidgetInfo> scope_widget_info (widget->CreateScopeWidgetInfo());
  1109. QuickWidgetInfoList quick_widget_info_list;
  1110. if (scope_widget_info.get() &&
  1111. OpStatus::IsSuccess(scope_widget_info->AddQuickWidgetInfoItems(quick_widget_info_list, TRUE, FALSE)))
  1112. {
  1113. QuickWidgetInfo *widget_info_item;
  1114. // Get the current mouse position
  1115. OpPoint mouse_position = g_input_manager->GetMousePosition();
  1116. // Find the item that the mouse is over and report that back
  1117. for (UINT32 i = 0; i < quick_widget_info_list.GetQuickwidgetListRef().GetCount(); i++)
  1118. {
  1119. widget_info_item = quick_widget_info_list.GetQuickwidgetListRef().Get(i);
  1120. OpRect widget_rect;
  1121. widget_rect.Set(widget_info_item->GetRect().GetX(), widget_info_item->GetRect().GetY(), widget_info_item->GetRect().GetWidth(), widget_info_item->GetRect().GetHeight());
  1122. // Found the item so set it and move on to the widget itself
  1123. if (widget_rect.Contains(mouse_position))
  1124. {
  1125. // This is a sub-item of the item below so we set add_to_path to false
  1126. // and add this to the access path after GetQuickWidgetInfoToolTip for the item below is called
  1127. GetQuickWidgetInfoToolTip(*widget_info_item, tooltip_text, watir_access_path, FALSE, FALSE);
  1128. BuildWatirAccessString(*widget_info_item, subitem_access, FALSE);
  1129. tooltip_text.Append("\n");
  1130. break;
  1131. }
  1132. }
  1133. }
  1134. QuickWidgetInfo widget_info;
  1135. // Skip composite
  1136. if (widget->GetType() == OpTypedObject::WIDGET_TYPE_COMPOSITE)
  1137. {
  1138. widget = widget->GetParent();
  1139. if (widget->GetType() == OpTypedObject::WIDGET_TYPE)
  1140. widget = widget->GetParent();
  1141. }
  1142. // If EditField inside OpDropDown -> Skip the editfield
  1143. if (widget->GetType() == OpTypedObject::WIDGET_TYPE_EDIT && widget->GetParent() &&
  1144. widget->GetParent()->GetType() == OpTypedObject::WIDGET_TYPE_DROPDOWN &&
  1145. widget->GetName().IsEmpty())
  1146. {
  1147. widget = widget->GetParent();
  1148. }
  1149. // If EditField inside QuickFind -> Skip the editfield
  1150. else if (widget->GetType() == OpTypedObject::WIDGET_TYPE_EDIT && widget->GetParent() &&
  1151. widget->GetParent()->GetType() == OpTypedObject::WIDGET_TYPE_QUICK_FIND)
  1152. {
  1153. widget = widget->GetParent();
  1154. }
  1155. // Hack to get the addressfield and searchfields correct.
  1156. else if (widget->GetType() == OpTypedObject::WIDGET_TYPE_EDIT && widget->GetParent() &&
  1157. widget->GetParent()->GetType() == OpTypedObject::WIDGET_TYPE_ADDRESS_DROPDOWN &&
  1158. widget->GetName().IsEmpty())
  1159. {
  1160. // Basically, skip me, take my parent instead:
  1161. widget = widget->GetParent();
  1162. }
  1163. else if ((widget->GetType() == OpTypedObject::WIDGET_TYPE_SEARCH_EDIT || widget->GetType() == OpTypedObject::WIDGET_TYPE_EDIT)
  1164. && widget->GetParent() && //widget->GetParent()->GetType() == OpTypedObject::WIDGET_TYPE_SEARCH_DROPDOWN &&
  1165. widget->GetName().IsEmpty())
  1166. {
  1167. // Skip me, my parent and its parent ... duh
  1168. OpWidget* special = widget->GetParent();
  1169. if (special->GetParent() && special->GetParent()->GetType() == OpTypedObject::WIDGET_TYPE_SEARCH_SPECIAL_DROPDOWN)
  1170. {
  1171. if (special->GetParent() && special->GetParent()->GetType() == OpTypedObject::WIDGET_TYPE_SEARCH_SPECIAL_DROPDOWN)
  1172. {
  1173. special = special->GetParent();
  1174. widget = special->GetParent();
  1175. }
  1176. }
  1177. }
  1178. //Skip the children of OpPasswordStrength()
  1179. else if (widget->GetParent() && widget->GetParent()->GetType() == OpTypedObject::WIDGET_TYPE_PASSWORD_STRENGTH)
  1180. {
  1181. widget = widget->GetParent();
  1182. }
  1183. if (widget && widget->GetType() != OpTypedObject::WIDGET_TYPE_ROOT)
  1184. {
  1185. // Convert the widget info to quick widget info
  1186. RETURN_VOID_IF_ERROR(SetQuickWidgetInfo(widget_info, widget));
  1187. // TODO: FIXME. check_parent doesn't need to be set here although this might be for example a treeview
  1188. // that is the parent of a treeitem
  1189. GetQuickWidgetInfoToolTip(widget_info, tooltip_text, watir_access_path, TRUE, FALSE, widget);
  1190. }
  1191. // Now add the path to the subitem, if any
  1192. watir_access_path.Append(subitem_access);
  1193. // Add information about which window the widget is in
  1194. DesktopWindow *dw = widget->GetParentDesktopWindow();
  1195. if (dw)
  1196. {
  1197. DesktopWindowInfo window_info;
  1198. if (OpStatus::IsSuccess(SetDesktopWindowInfo(window_info, dw)))
  1199. {
  1200. const char *temp_str;
  1201. switch (window_info.GetState())
  1202. {
  1203. case DesktopWindowInfo::DESKTOPWINDOWSTATE_RESTORED:
  1204. temp_str = "Restored";
  1205. break;
  1206. case DesktopWindowInfo::DESKTOPWINDOWSTATE_MINIMIZED:
  1207. temp_str = "Minimized";
  1208. break;
  1209. case DesktopWindowInfo::DESKTOPWINDOWSTATE_MAXIMIZED:
  1210. temp_str = "Maximized";
  1211. break;
  1212. case DesktopWindowInfo::DESKTOPWINDOWSTATE_FULLSCREEN:
  1213. temp_str = "Fullscreen";
  1214. break;
  1215. default:
  1216. temp_str = "Unknown State";
  1217. break;
  1218. }
  1219. OpString window_state;
  1220. OpStatus::Ignore(window_state.Set(temp_str));
  1221. temp_str = "Unknown";
  1222. switch (window_info.GetWindowType())
  1223. {
  1224. case DesktopWindowInfo::DESKTOPWINDOWTYPE_DIALOG:
  1225. temp_str = "Dialog";
  1226. break;
  1227. case DesktopWindowInfo::DESKTOPWINDOWTYPE_NORMAL:
  1228. temp_str = "Normal";
  1229. // fall through
  1230. default:
  1231. {
  1232. OpString path;
  1233. path.AppendFormat(".quick_window(:name, \"%s\")", window_info.GetName().HasContent() ? window_info.GetName().CStr() : UNI_L("[unnamed]"));
  1234. watir_access_path.Insert(0, path);
  1235. }
  1236. break;
  1237. }
  1238. OpString window_type;
  1239. OpStatus::Ignore(window_type.Set(temp_str));
  1240. // Add some space and a header
  1241. tooltip_text.AppendFormat("\nQuick Window Information:\n----------------------\n"
  1242. "ID: %u\n"
  1243. "Name: %s\n"
  1244. "Title: %s\n"
  1245. "Type: %s\n"
  1246. "State: %s\n"
  1247. "Pos: x=%u, y=%u\n"
  1248. "Size: width=%u, height=%u\n",
  1249. window_info.GetWindowID(),
  1250. window_info.GetName().HasContent() ? window_info.GetName().CStr() : UNI_L("[unnamed]"),
  1251. window_info.GetTitle().HasContent() ? window_info.GetTitle().CStr() : UNI_L("[no title]"),
  1252. window_type.CStr(),
  1253. window_state.CStr(),
  1254. window_info.GetRect().GetX(), window_info.GetRect().GetY(),
  1255. window_info.GetRect().GetWidth(), window_info.GetRect().GetHeight());
  1256. }
  1257. }
  1258. else // Parent window is a DesktopWidgetWindow, not a DesktopWindow
  1259. {
  1260. // TODO: Do we need the window in the path (in some cases?)?
  1261. }
  1262. watir_access_path.Insert(0, "browser");
  1263. watir_access_path.Append("\n\n");
  1264. tooltip_text.Insert(0, watir_access_path);
  1265. // If this is not in a Browser Window, add additional access path as alternative
  1266. int pos = watir_access_path.Find("quick_window(:name, \"Browser Window\")");
  1267. if (pos == KNotFound)
  1268. {
  1269. int winpos = watir_access_path.Find(".quick_window(");
  1270. if (pos != KNotFound)
  1271. {
  1272. int endparen = watir_access_path.Find(")", winpos);
  1273. int length = endparen - winpos;
  1274. if (length > 0)
  1275. {
  1276. OpString alternative_access_path;
  1277. alternative_access_path.Set(watir_access_path, 7); // 'browser'
  1278. alternative_access_path.Append(watir_access_path.CStr() + winpos + length + 1);
  1279. tooltip_text.Insert(0, alternative_access_path);
  1280. }
  1281. }
  1282. }
  1283. // Put the text into the clipboard so it can be used without having to type again
  1284. if (((g_op_system_info->GetShiftKeyState() & SHIFTKEY_ALT) == SHIFTKEY_ALT) &&
  1285. ((g_op_system_info->GetShiftKeyState() & SHIFTKEY_SHIFT) == SHIFTKEY_SHIFT))
  1286. OpStatus::Ignore(g_desktop_clipboard_manager->PlaceText(tooltip_text.CStr()));
  1287. else if ((g_op_system_info->GetShiftKeyState() & SHIFTKEY_ALT) == SHIFTKEY_ALT)
  1288. OpStatus::Ignore(g_desktop_clipboard_manager->PlaceText(watir_access_path.CStr()));
  1289. }
  1290. ////////////////////////////////////////////////////////////////////////
  1291. OP_STATUS OpScopeDesktopWindowManager::MenuItemPressed(const OpStringC& menu_text, BOOL popmenu)
  1292. {
  1293. // Build the menu item id
  1294. QuickMenuItemID menu_item_id;
  1295. RETURN_IF_ERROR(menu_item_id.SetMenuText(menu_text.CStr()));
  1296. menu_item_id.SetPopupMenu(popmenu);
  1297. // Send the event
  1298. return SendOnMenuItemPressed(menu_item_id);
  1299. }
  1300. ////////////////////////////////////////////////////////////////////////
  1301. OP_STATUS OpScopeDesktopWindowManager::DoGetActiveWindow(DesktopWindowID &out)
  1302. {
  1303. DesktopWindow* window = g_application->GetDesktopWindowCollection().GetCurrentInputWindow();
  1304. if (!window)
  1305. return SetCommandError(OpScopeTPHeader::InternalError, UNI_L("No active desktop window found"));
  1306. out.SetWindowID(window->GetID());
  1307. return OpStatus::OK;
  1308. }
  1309. OP_STATUS OpScopeDesktopWindowManager::DoListWindows(DesktopWindowList &out)
  1310. {
  1311. OpVector<DesktopWindow> windows;
  1312. RETURN_IF_ERROR(g_application->GetDesktopWindowCollection().GetDesktopWindows(windows));
  1313. for (UINT32 i = 0; i < windows.GetCount(); i++)
  1314. {
  1315. DesktopWindow* window = windows.Get(i);
  1316. if (!window)
  1317. return SetCommandError(OpScopeTPHeader::InternalError, UNI_L("Desktop window not found"));
  1318. OpAutoPtr<DesktopWindowInfo> info(OP_NEW(DesktopWindowInfo, ()));
  1319. if (info.get() == NULL)
  1320. return OpStatus::ERR_NO_MEMORY;
  1321. RETURN_IF_ERROR(SetDesktopWindowInfo(*info.get(), window));
  1322. RETURN_IF_ERROR(out.GetWindowListRef().Add(info.get()));
  1323. info.release();
  1324. }
  1325. for (UINT32 i = 0; i < m_widget_windows.GetCount(); i++)
  1326. {
  1327. DesktopWidgetWindow* window = m_widget_windows.Get(i);
  1328. if (!window)
  1329. return SetCommandError(OpScopeTPHeader::InternalError, UNI_L("Desktop window not found"));
  1330. OpAutoPtr<DesktopWindowInfo> info(OP_NEW(DesktopWindowInfo, ()));
  1331. if (info.get() == NULL)
  1332. return OpStatus::ERR_NO_MEMORY;
  1333. RETURN_IF_ERROR(SetDesktopWindowInfo(*info.get(), window));
  1334. RETURN_IF_ERROR(out.GetWindowListRef().Add(info.get()));
  1335. info.release();
  1336. }
  1337. return OpStatus::OK;
  1338. }
  1339. DesktopWidgetWindow* OpScopeDesktopWindowManager::GetDesktopWidgetWindow(INT32 id)
  1340. {
  1341. for (int i = 0; i < (int)m_widget_windows.GetCount(); i++)
  1342. {
  1343. DesktopWidgetWindow* win = (DesktopWidgetWindow*) m_widget_windows.Get(i);
  1344. if (win && win->GetID() == id)
  1345. return win;
  1346. }
  1347. return NULL;
  1348. }
  1349. OP_STATUS OpScopeDesktopWindowManager::DoPressQuickMenuItem(const QuickMenuItemID &in)
  1350. {
  1351. m_system_input_pi->PressMenu(in.GetMenuText(), in.GetPopupMenu() ? true : false);
  1352. return OpStatus::OK;
  1353. }
  1354. OP_STATUS OpScopeDesktopWindowManager::DoListQuickWidgets(const DesktopWindowID &in, QuickWidgetInfoList &out)
  1355. {
  1356. OP_STATUS status = OpStatus::OK;
  1357. OpVector<OpWidget> widgets;
  1358. DesktopWindow* window = g_application->GetDesktopWindowCollection().GetDesktopWindowByID(in.GetWindowID());
  1359. // If it's not in the desktopwindowcollection, it might be a DesktopWidgetWindow
  1360. if (!window)
  1361. {
  1362. DesktopWidgetWindow* win = GetDesktopWidgetWindow(in.GetWindowID());
  1363. if (!win)
  1364. return SetCommandError(OpScopeTPHeader::InternalError, UNI_L("Desktop window not found"));
  1365. status = win->ListWidgets(widgets);
  1366. }
  1367. else
  1368. {
  1369. status = window->ListWidgets(widgets);
  1370. }
  1371. if (OpStatus::IsSuccess(status))
  1372. {
  1373. for (UINT32 i = 0; i < widgets.GetCount(); i++)
  1374. {
  1375. OpWidget* widget = widgets.Get(i);
  1376. OpAutoPtr<QuickWidgetInfo> info(OP_NEW(QuickWidgetInfo, ()));
  1377. if (info.get() == NULL)
  1378. return OpStatus::ERR_NO_MEMORY;
  1379. RETURN_IF_ERROR(SetQuickWidgetInfo(*info.get(), widget));
  1380. RETURN_IF_ERROR(out.GetQuickwidgetListRef().Add(info.get()));
  1381. info.release();
  1382. // Add any further breakup of the widget that may be required to
  1383. // describe it to the UI automation system
  1384. OpAutoPtr<OpScopeWidgetInfo> widget_info (widget->CreateScopeWidgetInfo());
  1385. if (widget_info.get())
  1386. RETURN_IF_ERROR(widget_info->AddQuickWidgetInfoItems(out, FALSE, TRUE));
  1387. }
  1388. }
  1389. return OpStatus::OK;
  1390. }
  1391. OP_STATUS OpScopeDesktopWindowManager::GetWidgetInWidgetWindow(DesktopWidgetWindow* window, const QuickWidgetSearch& in, QuickWidgetInfo& out)
  1392. {
  1393. if (!window) return OpStatus::ERR;
  1394. OpWidget* widget = NULL;
  1395. if (in.GetSearchType() == QuickWidgetSearch::QUICKWIDGETSEARCHTYPE_NAME)
  1396. {
  1397. OpString8 name;
  1398. name.Set(in.GetData().CStr());
  1399. widget = window->GetWidgetByName(name); // label_for_blah
  1400. }
  1401. else if (in.GetSearchType() == QuickWidgetSearch::QUICKWIDGETSEARCHTYPE_TEXT)
  1402. {
  1403. OpString8 name;
  1404. name.Set(in.GetData().CStr());
  1405. widget = window->GetWidgetByText(name);
  1406. }
  1407. else
  1408. {
  1409. return SetCommandError(OpScopeTPHeader::InternalError, UNI_L("Quick widget search type not supported"));
  1410. }
  1411. // Make sure we actually found a widget
  1412. if (!widget)
  1413. {
  1414. return SetCommandError(OpScopeTPHeader::InternalError, UNI_L("Quick widget not found"));
  1415. }
  1416. RETURN_IF_ERROR(SetQuickWidgetInfo(out, widget));
  1417. return OpStatus::OK;
  1418. }
  1419. /**
  1420. * OBS: OBS: This isn't used currently as we rather send the whole widget list to webdriver, and search there.
  1421. * However, if this should be used, note that the name of tab buttons is not stored in widget->m_name (retrieved
  1422. * by widget->GetName() but generated from it's position, so searching for a tabbutton by name
  1423. * without modifying this won't work
  1424. *
  1425. **/
  1426. OP_STATUS OpScopeDesktopWindowManager::DoGetQuickWidget(const QuickWidgetSearch& in, QuickWidgetInfo& out)
  1427. {
  1428. UINT32 window_id = in.GetWindowID().GetWindowID();
  1429. DesktopWindow* window = g_application->GetDesktopWindowCollection().GetDesktopWindowByID(window_id);
  1430. if (!window)
  1431. {
  1432. DesktopWidgetWindow* win = GetDesktopWidgetWindow(window_id);
  1433. if (win)
  1434. return GetWidgetInWidgetWindow(win, in, out);
  1435. return SetCommandError(OpScopeTPHeader::InternalError, UNI_L("Desktop window not found"));
  1436. }
  1437. OpWidget* widget = NULL;
  1438. if (in.GetSearchType() == QuickWidgetSearch::QUICKWIDGETSEARCHTYPE_NAME)
  1439. {
  1440. OpString8 name;
  1441. name.Set(in.GetData().CStr());
  1442. widget = window->GetWidgetByName(name); // label_for_blah
  1443. }
  1444. else if (in.GetSearchType() == QuickWidgetSearch::QUICKWIDGETSEARCHTYPE_TEXT)
  1445. {
  1446. OpString8 name;
  1447. name.Set(in.GetData().CStr());
  1448. widget = GetWidgetByText(window, name);
  1449. }
  1450. else
  1451. {
  1452. return SetCommandError(OpScopeTPHeader::InternalError, UNI_L("Quick widget search type not supported"));
  1453. }
  1454. // Make sure we actually found a widget
  1455. if (!widget)
  1456. {
  1457. return SetCommandError(OpScopeTPHeader::InternalError, UNI_L("Quick widget not found"));
  1458. }
  1459. RETURN_IF_ERROR(SetQuickWidgetInfo(out, widget));
  1460. return OpStatus::OK;
  1461. }
  1462. OP_STATUS OpScopeDesktopWindowManager::DoListQuickMenus(QuickMenuList &out)
  1463. {
  1464. /**
  1465. * First get all menubars. This is done through quick, as the menubars need to be tied to the windowId of the BrowserDesktopWindow
  1466. */
  1467. #ifndef _MACINTOSH_
  1468. if (g_pcui->GetIntegerPref(PrefsCollectionUI::ShowMenu))
  1469. {
  1470. OpVector<DesktopWindow> main_windows;
  1471. if (OpStatus::IsSuccess(g_application->GetDesktopWindowCollection().GetDesktopWindows(OpTypedObject::WINDOW_TYPE_BROWSER, main_windows)))
  1472. {
  1473. for (UINT32 i = 0; i < main_windows.GetCount(); i++)
  1474. {
  1475. BrowserDesktopWindow* win = static_cast<BrowserDesktopWindow*>(main_windows.Get(i));
  1476. if (win)
  1477. {
  1478. OpAutoPtr<QuickMenuInfo> info(OP_NEW(QuickMenuInfo, ()));
  1479. if (info.get() == NULL)
  1480. return OpStatus::ERR_NO_MEMORY;
  1481. if (win->GetMenubarQuickMenuInfoItems(*info.get()))
  1482. {
  1483. RETURN_IF_ERROR(out.GetMenuListRef().Add(info.get()));
  1484. info.release();
  1485. }
  1486. }
  1487. }
  1488. }
  1489. }
  1490. #endif // _MACINTOSH_
  1491. // Get PopupMenus
  1492. /*bool res = */g_desktop_popup_menu_handler->ListPopupMenuInfo(out);
  1493. return OpStatus::OK;
  1494. }
  1495. // This is done on the Java side instead
  1496. OpWidget* OpScopeDesktopWindowManager::GetWidgetByText(DesktopWindow* window, OpString8& text)
  1497. {
  1498. if (!window || text.IsEmpty())
  1499. return NULL;
  1500. OpVector<OpWidget> widgets;
  1501. if (OpStatus::IsSuccess(window->ListWidgets(widgets)))
  1502. {
  1503. for (UINT32 i = 0; i < widgets.GetCount(); i++)
  1504. {
  1505. OpWidget* widget = widgets.Get(i);
  1506. OpString wdg_text;
  1507. if (widget && OpStatus::IsSuccess(widget->GetText(wdg_text)) && wdg_text.HasContent())
  1508. {
  1509. OpString8 widget_text;
  1510. widget_text.Set(wdg_text);
  1511. if (widget_text.Compare(text) == 0)
  1512. {
  1513. return widget;
  1514. }
  1515. }
  1516. }
  1517. }
  1518. return NULL;
  1519. }