diff --git a/.gitignore b/.gitignore index 4696e0d181a..c7210337073 100644 --- a/.gitignore +++ b/.gitignore @@ -150,3 +150,4 @@ xcuserdata Manifest.java +platform/wm/rhodes/emulator/GeneratedFiles/* diff --git a/platform/wm/RhoLib/RhoLib.vcproj b/platform/wm/RhoLib/RhoLib.vcproj index 02c2f9cb194..faff048c57b 100644 --- a/platform/wm/RhoLib/RhoLib.vcproj +++ b/platform/wm/RhoLib/RhoLib.vcproj @@ -176,8 +176,8 @@ @@ -252,8 +252,8 @@ @@ -467,8 +467,8 @@ @@ -542,8 +542,8 @@ @@ -617,8 +617,8 @@ @@ -693,8 +693,8 @@ @@ -720,6 +720,7 @@ PreprocessorDefinitions="_DEBUG;DEBUG;WIN32;_WINDOWS" MinimalRebuild="true" RuntimeLibrary="1" + TreatWChar_tAsBuiltInType="false" UsePrecompiledHeader="0" WarningLevel="3" DebugInformationFormat="3" @@ -759,8 +760,8 @@ @@ -835,8 +836,8 @@ @@ -911,8 +912,8 @@ @@ -986,8 +987,8 @@ @@ -1012,6 +1013,7 @@ AdditionalIncludeDirectories="../../shared/ruby;../../shared" PreprocessorDefinitions="_NDEBUG;NDEBUG;WIN32;_WINDOWS" RuntimeLibrary="0" + TreatWChar_tAsBuiltInType="false" UsePrecompiledHeader="0" WarningLevel="3" DebugInformationFormat="3" @@ -1051,8 +1053,8 @@ @@ -1126,8 +1128,8 @@ diff --git a/platform/wm/rhodes.sln b/platform/wm/rhodes.sln index 366b0743847..505d19b5e17 100644 --- a/platform/wm/rhodes.sln +++ b/platform/wm/rhodes.sln @@ -97,6 +97,7 @@ Global {95D5D2E5-FEF5-4CA9-88CF-FCB0F7465E62}.EmulatorRelease|Smartphone 2003 (ARMV4).ActiveCfg = EmulatorRelease|Smartphone 2003 (ARMV4) {95D5D2E5-FEF5-4CA9-88CF-FCB0F7465E62}.EmulatorRelease|Smartphone 2003 (ARMV4).Deploy.0 = EmulatorRelease|Smartphone 2003 (ARMV4) {95D5D2E5-FEF5-4CA9-88CF-FCB0F7465E62}.EmulatorRelease|Win32.ActiveCfg = EmulatorRelease|Win32 + {95D5D2E5-FEF5-4CA9-88CF-FCB0F7465E62}.EmulatorRelease|Win32.Build.0 = EmulatorRelease|Win32 {95D5D2E5-FEF5-4CA9-88CF-FCB0F7465E62}.EmulatorRelease|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = EmulatorRelease|Windows Mobile 6 Professional SDK (ARMV4I) {95D5D2E5-FEF5-4CA9-88CF-FCB0F7465E62}.EmulatorRelease|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = EmulatorRelease|Windows Mobile 6 Professional SDK (ARMV4I) {95D5D2E5-FEF5-4CA9-88CF-FCB0F7465E62}.EmulatorRelease|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = EmulatorRelease|Windows Mobile 6 Professional SDK (ARMV4I) @@ -148,6 +149,7 @@ Global {AA77BEC0-2A60-4589-A784-7D78F60B35B6}.EmulatorRelease|Smartphone 2003 (ARMV4).ActiveCfg = EmulatorRelease|Smartphone 2003 (ARMV4) {AA77BEC0-2A60-4589-A784-7D78F60B35B6}.EmulatorRelease|Smartphone 2003 (ARMV4).Deploy.0 = EmulatorRelease|Smartphone 2003 (ARMV4) {AA77BEC0-2A60-4589-A784-7D78F60B35B6}.EmulatorRelease|Win32.ActiveCfg = EmulatorRelease|Win32 + {AA77BEC0-2A60-4589-A784-7D78F60B35B6}.EmulatorRelease|Win32.Build.0 = EmulatorRelease|Win32 {AA77BEC0-2A60-4589-A784-7D78F60B35B6}.EmulatorRelease|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = EmulatorRelease|Windows Mobile 6 Professional SDK (ARMV4I) {AA77BEC0-2A60-4589-A784-7D78F60B35B6}.EmulatorRelease|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = EmulatorRelease|Windows Mobile 6 Professional SDK (ARMV4I) {AA77BEC0-2A60-4589-A784-7D78F60B35B6}.EmulatorRelease|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = EmulatorRelease|Windows Mobile 6 Professional SDK (ARMV4I) @@ -198,6 +200,7 @@ Global {B381B601-04B1-475B-B635-003F8E7DA3A9}.EmulatorRelease|Smartphone 2003 (ARMV4).ActiveCfg = EmulatorRelease|Smartphone 2003 (ARMV4) {B381B601-04B1-475B-B635-003F8E7DA3A9}.EmulatorRelease|Smartphone 2003 (ARMV4).Deploy.0 = EmulatorRelease|Smartphone 2003 (ARMV4) {B381B601-04B1-475B-B635-003F8E7DA3A9}.EmulatorRelease|Win32.ActiveCfg = EmulatorRelease|Win32 + {B381B601-04B1-475B-B635-003F8E7DA3A9}.EmulatorRelease|Win32.Build.0 = EmulatorRelease|Win32 {B381B601-04B1-475B-B635-003F8E7DA3A9}.EmulatorRelease|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = EmulatorRelease|Windows Mobile 6 Professional SDK (ARMV4I) {B381B601-04B1-475B-B635-003F8E7DA3A9}.EmulatorRelease|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = EmulatorRelease|Windows Mobile 6 Professional SDK (ARMV4I) {B381B601-04B1-475B-B635-003F8E7DA3A9}.EmulatorRelease|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = EmulatorRelease|Windows Mobile 6 Professional SDK (ARMV4I) @@ -248,6 +251,7 @@ Global {6F57C60E-C083-4D46-A3B9-E17948A33518}.EmulatorRelease|Smartphone 2003 (ARMV4).ActiveCfg = EmulatorRelease|Smartphone 2003 (ARMV4) {6F57C60E-C083-4D46-A3B9-E17948A33518}.EmulatorRelease|Smartphone 2003 (ARMV4).Deploy.0 = EmulatorRelease|Smartphone 2003 (ARMV4) {6F57C60E-C083-4D46-A3B9-E17948A33518}.EmulatorRelease|Win32.ActiveCfg = EmulatorRelease|Win32 + {6F57C60E-C083-4D46-A3B9-E17948A33518}.EmulatorRelease|Win32.Build.0 = EmulatorRelease|Win32 {6F57C60E-C083-4D46-A3B9-E17948A33518}.EmulatorRelease|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = EmulatorRelease|Windows Mobile 6 Professional SDK (ARMV4I) {6F57C60E-C083-4D46-A3B9-E17948A33518}.EmulatorRelease|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = EmulatorRelease|Windows Mobile 6 Professional SDK (ARMV4I) {6F57C60E-C083-4D46-A3B9-E17948A33518}.EmulatorRelease|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = EmulatorRelease|Windows Mobile 6 Professional SDK (ARMV4I) @@ -294,6 +298,7 @@ Global {F196A418-11F1-4067-9F4F-BCC7D70E6EC5}.EmulatorRelease|Smartphone 2003 (ARMV4).ActiveCfg = EmulatorRelease|Smartphone 2003 (ARMV4) {F196A418-11F1-4067-9F4F-BCC7D70E6EC5}.EmulatorRelease|Smartphone 2003 (ARMV4).Deploy.0 = EmulatorRelease|Smartphone 2003 (ARMV4) {F196A418-11F1-4067-9F4F-BCC7D70E6EC5}.EmulatorRelease|Win32.ActiveCfg = EmulatorRelease|Win32 + {F196A418-11F1-4067-9F4F-BCC7D70E6EC5}.EmulatorRelease|Win32.Build.0 = EmulatorRelease|Win32 {F196A418-11F1-4067-9F4F-BCC7D70E6EC5}.EmulatorRelease|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = EmulatorRelease|Windows Mobile 6 Professional SDK (ARMV4I) {F196A418-11F1-4067-9F4F-BCC7D70E6EC5}.EmulatorRelease|Windows Mobile 5.0 Smartphone SDK (ARMV4I).ActiveCfg = EmulatorRelease|Windows Mobile 6 Professional SDK (ARMV4I) {F196A418-11F1-4067-9F4F-BCC7D70E6EC5}.EmulatorRelease|Windows Mobile 6 Professional SDK (ARMV4I).ActiveCfg = EmulatorRelease|Windows Mobile 6 Professional SDK (ARMV4I) diff --git a/platform/wm/rhodes/MainWindow.h b/platform/wm/rhodes/MainWindow.h index 6ebf291e156..522cd3c6235 100644 --- a/platform/wm/rhodes/MainWindow.h +++ b/platform/wm/rhodes/MainWindow.h @@ -2,6 +2,8 @@ #pragma once +#ifndef RHODES_EMULATOR + #if !defined(_WIN32_WCE) || defined( OS_PLATFORM_CE ) #include #include @@ -256,4 +258,10 @@ class CMainWindow : #if !defined(_WIN32_WCE) || defined( OS_PLATFORM_CE ) HBITMAP SHLoadImageFile ( LPCTSTR pszFileName ); -#endif \ No newline at end of file +#endif + +#else + +#include "emulator\MainWindowQt.h" + +#endif diff --git a/platform/wm/rhodes/RhoNativeViewManager.cpp b/platform/wm/rhodes/RhoNativeViewManager.cpp index 056cd7e2d62..b09dee65880 100644 --- a/platform/wm/rhodes/RhoNativeViewManager.cpp +++ b/platform/wm/rhodes/RhoNativeViewManager.cpp @@ -72,7 +72,9 @@ class RhoNativeViewRunnable_OpenViewCommand : public RhoNativeViewRunnable { virtual void run() { CMainWindow* mw = Rhodes_getMainWindow(); String sn(mView->factory_holder->viewtype); +#ifndef RHODES_EMULATOR mw->openNativeView(mView->factory_holder->factory, mView->n_view, sn); +#endif //delete this; } @@ -86,7 +88,9 @@ class RhoNativeViewRunnable_CloseViewCommand : public RhoNativeViewRunnable { } virtual void run() { CMainWindow* mw = Rhodes_getMainWindow(); +#ifndef RHODES_EMULATOR mw->closeNativeView(); +#endif //delete this; } }; diff --git a/platform/wm/rhodes/Rhodes.cpp b/platform/wm/rhodes/Rhodes.cpp index 6c5b1c6e2e4..5d8f3147564 100644 --- a/platform/wm/rhodes/Rhodes.cpp +++ b/platform/wm/rhodes/Rhodes.cpp @@ -110,6 +110,7 @@ public : } // Note: In this sample, we don't respond differently to different hr success codes. +#ifndef RHODES_EMULATOR // Allow only one instance of the application. // the "| 0x01" activates the correct owned window of the previous instance's main window HWND hWnd = NULL; @@ -128,6 +129,7 @@ public : SetForegroundWindow( HWND( DWORD(hWnd) | 0x01 ) ); return S_FALSE; } +#endif rho_logconf_Init(m_strRootPath.c_str()); @@ -195,7 +197,11 @@ public : dwStyle |= WS_OVERLAPPEDWINDOW; #endif // Create the main application window +#ifdef RHODES_EMULATOR + m_appWindow.Initialize(convertToStringW(strTitle).c_str()); +#else m_appWindow.Create(NULL, CWindow::rcDefault, convertToStringW(strTitle).c_str(), dwStyle); +#endif if (NULL == m_appWindow.m_hWnd) { return S_FALSE; @@ -243,6 +249,9 @@ public : void RunMessageLoop( ) throw( ) { +#ifdef RHODES_EMULATOR + m_appWindow.MessageLoop(); +#else MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { @@ -252,6 +261,7 @@ public : DispatchMessage(&msg); } } +#endif #if defined(OS_WINCE)&& !defined( OS_PLATFORM_CE ) CGPSController* pGPS = CGPSController::Instance(); diff --git a/platform/wm/rhodes/emulator/ExternalWebView.cpp b/platform/wm/rhodes/emulator/ExternalWebView.cpp new file mode 100644 index 00000000000..d4853d12641 --- /dev/null +++ b/platform/wm/rhodes/emulator/ExternalWebView.cpp @@ -0,0 +1,20 @@ +#include "ExternalWebView.h" +#include "ui_ExternalWebView.h" + +ExternalWebView::ExternalWebView(QWidget *parent) : + QWidget(parent), + ui(new Ui::ExternalWebView) +{ + ui->setupUi(this); + this->ui->webView->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true); + this->move(0,0); +} + +ExternalWebView::~ExternalWebView() +{ +} + +void ExternalWebView::navigate(QUrl url) +{ + ui->webView->setUrl(url); +} diff --git a/platform/wm/rhodes/emulator/ExternalWebView.h b/platform/wm/rhodes/emulator/ExternalWebView.h new file mode 100644 index 00000000000..a04cfc89e43 --- /dev/null +++ b/platform/wm/rhodes/emulator/ExternalWebView.h @@ -0,0 +1,23 @@ +#ifndef EXTERNALWEBVIEW_H +#define EXTERNALWEBVIEW_H + +#include +#include + +namespace Ui { + class ExternalWebView; +} + +class ExternalWebView : public QWidget +{ + Q_OBJECT + +public: + explicit ExternalWebView(QWidget *parent = 0); + ~ExternalWebView(); + void navigate(QUrl url); +private: + Ui::ExternalWebView *ui; +}; + +#endif // EXTERNALWEBVIEW_H diff --git a/platform/wm/rhodes/emulator/ExternalWebView.ui b/platform/wm/rhodes/emulator/ExternalWebView.ui new file mode 100644 index 00000000000..f0c0c3a7f89 --- /dev/null +++ b/platform/wm/rhodes/emulator/ExternalWebView.ui @@ -0,0 +1,46 @@ + + + ExternalWebView + + + + 0 + 0 + 800 + 600 + + + + External Browser + + + + + + + 0 + + + 0 + + + + + + about:blank + + + + + + + + + QWebView + QWidget +
QtWebKit/QWebView
+
+
+ + +
diff --git a/platform/wm/rhodes/emulator/MainWindowCallback.h b/platform/wm/rhodes/emulator/MainWindowCallback.h new file mode 100644 index 00000000000..edfb60780e7 --- /dev/null +++ b/platform/wm/rhodes/emulator/MainWindowCallback.h @@ -0,0 +1,18 @@ +#ifndef MAINWINDOWCALLBACK_H +#define MAINWINDOWCALLBACK_H + +#include + +class IMainWindowCallback +{ +public: + virtual void updateSizeProperties(int width, int height) = 0; + virtual void onActivate(int active) = 0; + virtual void logEvent(const ::std::string& message) = 0; + virtual void createCustomMenu(void) = 0; + virtual void onCustomMenuItemCommand(int nItemPos) = 0; +protected: + virtual ~IMainWindowCallback() {}; +}; + +#endif // MAINWINDOWCALLBACK_H diff --git a/platform/wm/rhodes/emulator/MainWindowProxy.cpp b/platform/wm/rhodes/emulator/MainWindowProxy.cpp new file mode 100644 index 00000000000..608b42f753b --- /dev/null +++ b/platform/wm/rhodes/emulator/MainWindowProxy.cpp @@ -0,0 +1,267 @@ +#pragma warning(disable:4996) +#include "MainWindowProxy.h" +#include "common/RhodesApp.h" +#include "common/RhoConf.h" +#include "common/RhoFilePath.h" +#include "NativeToolbarQt.h" +#include "rho/rubyext/NativeToolbarExt.h" +#undef null +#include +#include +#include +#include "QtMainWindow.h" + +IMPLEMENT_LOGCLASS(CMainWindowProxy,"MainWindowProxy"); + +extern "C" int rho_wmsys_has_touchscreen(); + +using namespace rho; +using namespace rho::common; + +CMainWindowProxy::CMainWindowProxy(void): + qtApplication(NULL), + qtMainWindow(NULL) +{ +} + +CMainWindowProxy::~CMainWindowProxy(void) +{ + if (qtMainWindow) delete (QtMainWindow*)qtMainWindow; + if (qtApplication) delete (QApplication*)qtApplication; +} + +void CMainWindowProxy::navigate(const wchar_t* url) +{ + LOG(INFO) + "navigate: '"+url+"'"; + ((QtMainWindow*)qtMainWindow)->navigate(QUrl(QString::fromWCharArray(url))); +} + +void CMainWindowProxy::setCallback(IMainWindowCallback* callback) +{ + ((QtMainWindow*)qtMainWindow)->setCallback(callback); +} + +void* CMainWindowProxy::init(IMainWindowCallback* callback, const wchar_t* title) +{ + int argc = 0; + qtApplication = (void*)new QApplication(argc, 0); + qtMainWindow = (void*)new QtMainWindow(); + ((QtMainWindow*)qtMainWindow)->setWindowTitle(QString::fromWCharArray(title)); + ((QtMainWindow*)qtMainWindow)->setCallback(callback); + ((QtMainWindow*)qtMainWindow)->show(); + + return (void*)((QtMainWindow*)qtMainWindow)->winId(); +} + +void CMainWindowProxy::messageLoop(void) +{ + qApp->exec(); +} + +void CMainWindowProxy::GoBack(void) +{ + LOG(INFO) + "back"; + ((QtMainWindow*)qtMainWindow)->GoBack(); +} + +void CMainWindowProxy::GoForward(void) +{ + LOG(INFO) + "forward"; + ((QtMainWindow*)qtMainWindow)->GoForward(); +} + +void CMainWindowProxy::Refresh(void) +{ + LOG(INFO) + "refresh"; + ((QtMainWindow*)qtMainWindow)->Refresh(); +} + +bool CMainWindowProxy::isStarted() +{ + return true; +} + +int CMainWindowProxy::getHeight() +{ + return ((QtMainWindow*)qtMainWindow)->toolbarGetHeight(); +} + + +void CMainWindowProxy::removeToolbar() +{ + ((QtMainWindow*)qtMainWindow)->toolbarHide(); +} + +void CMainWindowProxy::removeAllButtons() +{ + ((QtMainWindow*)qtMainWindow)->toolbarRemoveAllButtons(); +} + +static QColor getColorFromString(const char* szColor) +{ + if ( !szColor || !*szColor ) + return QColor(0, 0, 0); + + int c = atoi(szColor); + + int cR = (c & 0xFF0000) >> 16; + int cG = (c & 0xFF00) >> 8; + int cB = (c & 0xFF); + + return QColor(cR, cG, cB); +} + +void CMainWindowProxy::createToolbar(rho_param *p) +{ + if (!rho_rhodesapp_check_mode() || !rho_wmsys_has_touchscreen() ) + return; + + int bar_type = TOOLBAR_TYPE; + QColor m_rgbBackColor = QColor(220,220,220); + QColor m_rgbMaskColor = QColor(255,255,255); + int m_nHeight = CNativeToolbar::MIN_TOOLBAR_HEIGHT; + + rho_param *params = NULL; + switch (p->type) + { + case RHO_PARAM_ARRAY: + params = p; + break; + case RHO_PARAM_HASH: + { + for (int i = 0, lim = p->v.hash->size; i < lim; ++i) + { + const char *name = p->v.hash->name[i]; + rho_param *value = p->v.hash->value[i]; + + if (strcasecmp(name, "background_color") == 0) + m_rgbBackColor = getColorFromString(value->v.string); + else if (strcasecmp(name, "mask_color") == 0) + m_rgbMaskColor = getColorFromString(value->v.string); + else if (strcasecmp(name, "view_height") == 0) + m_nHeight = atoi(value->v.string); + else if (strcasecmp(name, "buttons") == 0 || strcasecmp(name, "tabs") == 0) + params = value; + } + } + break; + default: { + LOG(ERROR) + "Unexpected parameter type for create_nativebar, should be Array or Hash"; + return; + } + } + + if (!params) { + LOG(ERROR) + "Wrong parameters for create_nativebar"; + return; + } + + int size = params->v.array->size; + if ( size == 0 ) + { + removeToolbar(); + return; + } + + removeAllButtons(); + + int nSeparators = 0; + bool wasSeparator = false; + for (int ipass=0; ipass < 2; ++ipass) { + for (int i = 0; i < size; ++i) + { + rho_param *hash = params->v.array->value[i]; + if (hash->type != RHO_PARAM_HASH) { + LOG(ERROR) + "Unexpected type of array item for create_nativebar, should be Hash"; + return; + } + + const char *label = NULL; + const char *action = NULL; + const char *icon = NULL; + const char *colored_icon = NULL; + int nItemWidth = 0; + + for (int j = 0, lim = hash->v.hash->size; j < lim; ++j) + { + const char *name = hash->v.hash->name[j]; + rho_param *value = hash->v.hash->value[j]; + if (value->type != RHO_PARAM_STRING) { + LOG(ERROR) + "Unexpected '" + name + "' type, should be String"; + return; + } + + if (strcasecmp(name, "label") == 0) + label = value->v.string; + else if (strcasecmp(name, "action") == 0) + action = value->v.string; + else if (strcasecmp(name, "icon") == 0) + icon = value->v.string; + else if (strcasecmp(name, "colored_icon") == 0) + colored_icon = value->v.string; + else if (strcasecmp(name, "width") == 0) + nItemWidth = atoi(value->v.string); + } + + if (label == NULL && bar_type == TOOLBAR_TYPE) + label = ""; + + if ( label == NULL || action == NULL) { + LOG(ERROR) + "Illegal argument for create_nativebar"; + return; + } + if ( strcasecmp(action, "forward") == 0 && rho_conf_getBool("jqtouch_mode") ) + continue; + + if (!action) action = ""; + + if (ipass==0) { + if (strcasecmp(action, "separator")==0) + ++nSeparators; + } else { + LOG(INFO) + "addToolbarButton: Label: '"+label+"';Action: '"+action+"'"; + if (strcasecmp(action, "separator")==0) { + if (nSeparators!=1) + ((QtMainWindow*)qtMainWindow)->toolbarAddSeparator(); + else + wasSeparator = true; + } else { + String strImagePath; + if ( icon && *icon ) + strImagePath = rho::common::CFilePath::join( RHODESAPP().getAppRootPath(), icon ); + else { + if ( strcasecmp(action, "options")==0 ) + strImagePath = "lib/res/options_btn.png"; + else if ( strcasecmp(action, "home")==0 ) + strImagePath = "lib/res/home_btn.png"; + else if ( strcasecmp(action, "refresh")==0 ) + strImagePath = "lib/res/refresh_btn.png"; + else if ( strcasecmp(action, "back")==0 ) + strImagePath = "lib/res/back_btn.png"; + else if ( strcasecmp(action, "forward")==0 ) + strImagePath = "lib/res/forward_btn.png"; + strImagePath = strImagePath.length() > 0 ? CFilePath::join( RHODESAPP().getRhoRootPath(), strImagePath) : String(); + } + + ((QtMainWindow*)qtMainWindow)->toolbarAddAction(QIcon(QString(strImagePath.c_str())), QString(label), action, wasSeparator); + } + } + } + } + ((QtMainWindow*)qtMainWindow)->toolbarShow(); +} + +void CMainWindowProxy::menuClear() +{ + ((QtMainWindow*)qtMainWindow)->menuClear(); +} + +void CMainWindowProxy::menuAddSeparator() +{ + ((QtMainWindow*)qtMainWindow)->menuAddSeparator(); +} + +void CMainWindowProxy::menuAddAction(const char* label, int item) +{ + ((QtMainWindow*)qtMainWindow)->menuAddAction(QString(label), item); +} diff --git a/platform/wm/rhodes/emulator/MainWindowProxy.h b/platform/wm/rhodes/emulator/MainWindowProxy.h new file mode 100644 index 00000000000..d85163769b5 --- /dev/null +++ b/platform/wm/rhodes/emulator/MainWindowProxy.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include "common/rhoparams.h" +#include "logging/RhoLog.h" +#include "MainWindowCallback.h" + +class CMainWindowProxy +{ + DEFINE_LOGCLASS; +public: + CMainWindowProxy(void); + ~CMainWindowProxy(void); + void* init(IMainWindowCallback* callback, const wchar_t* title); + void setCallback(IMainWindowCallback* callback); + void messageLoop(void); + void navigate(const wchar_t* url); + void GoBack(void); + void GoForward(void); + void Refresh(void); + // toolbar proxy + bool isStarted(); + int getHeight(); + void createToolbar(rho_param *p); + void removeToolbar(); + void removeAllButtons(); + // menu proxy + void menuClear(); + void menuAddSeparator(); + void menuAddAction(const char* label, int item); +private: + void* qtMainWindow; + void* qtApplication; +}; diff --git a/platform/wm/rhodes/emulator/MainWindowQt.cpp b/platform/wm/rhodes/emulator/MainWindowQt.cpp new file mode 100644 index 00000000000..c104711014f --- /dev/null +++ b/platform/wm/rhodes/emulator/MainWindowQt.cpp @@ -0,0 +1,339 @@ +// MainWindow.cpp: Defines main window for this application. + +#include "stdafx.h" +#include "MainWindowQt.h" +#include "common/RhoStd.h" +#include "common/StringConverter.h" +#include "camera/Camera.h" +#include "common/RhoFilePath.h" +#include "AppManager.h" + +IMPLEMENT_LOGCLASS(CMainWindow,"MainWindow"); + +#include "DateTimePicker.h" + +using namespace rho; +using namespace rho::common; + +extern "C" void rho_geoimpl_turngpsoff(); + +int CMainWindow::m_screenWidth; +int CMainWindow::m_screenHeight; + +CMainWindow::CMainWindow() { } + +CMainWindow::~CMainWindow() { } + +void CMainWindow::updateSizeProperties(int width, int height) +{ + m_screenWidth = width; + m_screenHeight = height; + LOGCONF().setLogView(&m_logView); +} + +void CMainWindow::logEvent(const ::std::string& message) +{ + LOG(INFO) + message; +} + +void CMainWindow::Navigate2(BSTR URL) { + String cleared_url = convertToStringA(OLE2CT(URL)); + if (!cleared_url.empty()) { + StringW cw = convertToStringW(cleared_url); + m_mainWindowProxy.navigate(cw.c_str()); + } +} + +HWND CMainWindow::Initialize(const wchar_t* title) +{ + HWND hWnd = (HWND)m_mainWindowProxy.init(this, title); + SubclassWindow(hWnd); + //rho_rhodesapp_callAppActiveCallback(1); + rho_rhodesapp_callUiCreatedCallback(); + return hWnd; +} + +HWND CMainWindow::getWebViewHWND() +{ + // TODO + return 0; +} + +void CMainWindow::MessageLoop(void) +{ + m_mainWindowProxy.messageLoop(); +} + +void CMainWindow::createCustomMenu(void) +{ + RHODESAPP().getAppMenu().copyMenuItems(m_arAppMenuItems); + //m_mainWindowProxy.createCustomMenu(); +#ifdef ENABLE_DYNAMIC_RHOBUNDLE + String strIndexPage = CFilePath::join(RHODESAPP().getStartUrl(),"index_erb.iseq"); + if ( RHODESAPP().getCurrentUrl().compare(RHODESAPP().getStartUrl()) == 0 || + RHODESAPP().getCurrentUrl().compare(strIndexPage) == 0 ) + m_arAppMenuItems.addElement(CAppMenuItem("Reload RhoBundle","reload_rhobundle")); +#endif //ENABLE_DYNAMIC_RHOBUNDLE + + //update UI with custom menu items + m_mainWindowProxy.menuClear(); + for ( unsigned int i = 0; i < m_arAppMenuItems.size(); i++) + { + CAppMenuItem& oItem = m_arAppMenuItems.elementAt(i); + if (oItem.m_eType == CAppMenuItem::emtSeparator) + m_mainWindowProxy.menuAddSeparator(); + else + { + m_mainWindowProxy.menuAddAction((oItem.m_eType == CAppMenuItem::emtClose ? "Exit" : oItem.m_strLabel.c_str()), i); + } + } +} + +void CMainWindow::onCustomMenuItemCommand(int nItemPos) +{ + if ( nItemPos < 0 || nItemPos >= (int)m_arAppMenuItems.size() ) + return; + + CAppMenuItem& oMenuItem = m_arAppMenuItems.elementAt(nItemPos); + if ( oMenuItem.m_eType == CAppMenuItem::emtUrl ) + { + if ( oMenuItem.m_strLink == "reload_rhobundle" ) + { + #ifdef ENABLE_DYNAMIC_RHOBUNDLE + if ( RHODESAPP().getRhobundleReloadUrl().length()>0 ) { + CAppManager::ReloadRhoBundle(m_hWnd,RHODESAPP().getRhobundleReloadUrl().c_str(), NULL); + } else { + MessageBox(_T("Path to the bundle is not defined."),_T("Information"), MB_OK | MB_ICONINFORMATION ); + } + #endif + return; + } + } + + oMenuItem.processCommand(); +} + + +// ************************************************************************** +// +// WM_xxx handlers +// +// ************************************************************************** + +void CMainWindow::performOnUiThread(rho::common::IRhoRunnable* pTask) +{ + PostMessage(WM_EXECUTE_RUNNABLE, 0, (LPARAM)pTask); +} +LRESULT CMainWindow::OnExecuteRunnable(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) +{ + rho::common::IRhoRunnable* pTask = (rho::common::IRhoRunnable*)lParam; + if (pTask) + { + pTask->runObject(); + delete pTask; + } + return 0; +} + +LRESULT CMainWindow::OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled) +{ + rho_rhodesapp_callUiDestroyedCallback(); + + if(m_logView.IsWindow()) { + m_logView.DestroyWindow(); + } + LOGCONF().setLogView(NULL); + + PostQuitMessage(0); + + bHandled = FALSE; // Allow ATL's default processing (e.g. NULLing m_hWnd) + return 0; +} + +void CMainWindow::onActivate(int active) +{ + rho_rhodesapp_callAppActiveCallback(active); + if (!active) + rho_geoimpl_turngpsoff(); +} + + +// ************************************************************************** +// +// WM_COMMAND handlers +// +// ************************************************************************** + +LRESULT CMainWindow::OnExitCommand(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ + SendMessage(WM_CLOSE); + return 0; +} + +LRESULT CMainWindow::OnNavigateBackCommand(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ + m_mainWindowProxy.GoBack(); + return 0; +} + +LRESULT CMainWindow::OnNavigateForwardCommand(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ + m_mainWindowProxy.GoForward(); + return 0; +} + +LRESULT CMainWindow::OnBackCommand(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ + RHODESAPP().navigateBack(); + return 0; +} + +LRESULT CMainWindow::OnLogCommand(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ + if ( !m_logView.IsWindow() ) { + LoadLibrary(_T("riched20.dll")); + m_logView.Create(NULL); + } + m_logView.ShowWindow(SW_SHOWNORMAL); + return 0; +} + +LRESULT CMainWindow::OnRefreshCommand(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/) +{ + m_mainWindowProxy.Refresh(); + return 0; +} + +LRESULT CMainWindow::OnNavigateCommand(WORD /*wNotifyCode*/, WORD /*wID*/, HWND hWndCtl, BOOL& /*bHandled*/) +{ + LPTSTR wcurl = (LPTSTR)hWndCtl; + if (wcurl) { + Navigate2(wcurl); + free(wcurl); + } + return 0; +} + +LRESULT CMainWindow::OnTakePicture(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) +{ + TCHAR image_uri[MAX_PATH]; + HRESULT status; + //TODO: show browse file dialog + wsprintf( image_uri, L"%s", L"dashboard.PNG"); + status = S_OK; + + RHODESAPP().callCameraCallback( (const char*)lParam, rho::common::convertToStringA(image_uri), + (status!= S_OK && status != S_FALSE ? "Error" : ""), status == S_FALSE); + + free ((void *)lParam); + return 0; +} + +LRESULT CMainWindow::OnSelectPicture(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) +{ + TCHAR image_uri[MAX_PATH]; + HRESULT status = S_OK; + Camera camera; + status = camera.selectPicture(this->m_hWnd,image_uri); + + RHODESAPP().callCameraCallback( (const char*)lParam, rho::common::convertToStringA(image_uri), + (status!= S_OK && status != S_FALSE ? "Error" : ""), status == S_FALSE); + + free ((void *)lParam); + + return 0; +} + +LRESULT CMainWindow::OnAlertShowPopup (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) +{ + /* TODO */ + StringW strAppName = RHODESAPP().getAppNameW(); + CAlertDialog::Params *params = (CAlertDialog::Params *)lParam; + + if (params->m_dlgType == CAlertDialog::Params::DLG_STATUS) + { + m_SyncStatusDlg.setStatusText(convertToStringW(params->m_message).c_str()); + m_SyncStatusDlg.setTitle( convertToStringW(params->m_title).c_str() ); + if ( !m_SyncStatusDlg.m_hWnd ) + m_SyncStatusDlg.Create(m_hWnd, 0); + else + { + m_SyncStatusDlg.ShowWindow(SW_SHOW); + m_SyncStatusDlg.BringWindowToTop(); + } + }else if (params->m_dlgType == CAlertDialog::Params::DLG_DEFAULT) { + MessageBox(convertToStringW(params->m_message).c_str(), strAppName.c_str(), MB_ICONWARNING | MB_OK); + } else if (params->m_dlgType == CAlertDialog::Params::DLG_CUSTOM) + { + if ( params->m_buttons.size() == 1 && strcasecmp(params->m_buttons[0].m_strCaption.c_str(), "ok") == 0) + MessageBox(convertToStringW(params->m_message).c_str(), convertToStringW(params->m_title).c_str(), MB_ICONWARNING | MB_OK); + else if (params->m_buttons.size() == 2 && strcasecmp(params->m_buttons[0].m_strCaption.c_str(), "ok") == 0 && + strcasecmp(params->m_buttons[1].m_strCaption.c_str(), "cancel") == 0) + { + int nRes = MessageBox(convertToStringW(params->m_message).c_str(), convertToStringW(params->m_title).c_str(), + MB_ICONWARNING | MB_OKCANCEL); + int nBtn = nRes == IDCANCEL ? 1 : 0; + RHODESAPP().callPopupCallback(params->m_callback, params->m_buttons[nBtn].m_strID, params->m_buttons[nBtn].m_strCaption); + } + else + { + if (m_alertDialog == NULL) + { + m_alertDialog = new CAlertDialog(params); + m_alertDialog->DoModal(); + delete m_alertDialog; + m_alertDialog = NULL; + } else { + LOG(WARNING) + "Trying to show alert dialog while it exists."; + } + } + } + + delete params; + /* */ + return 0; +} + +LRESULT CMainWindow::OnAlertHidePopup (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) +{ + /* TODO */ + if (m_alertDialog != NULL) { + m_alertDialog->EndDialog(0); + m_alertDialog = NULL; + } + /* */ + return 0; +} + +LRESULT CMainWindow::OnExecuteCommand(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/) { + RhoNativeViewRunnable* command = (RhoNativeViewRunnable*)wParam; + if (command != NULL) { + command->run(); + } + return 0; +} + +LRESULT CMainWindow::OnDateTimePicker (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/) +{ + CDateTimeMessage *msg = (CDateTimeMessage *)lParam; + int retCode = -1; + time_t ret_time = 0; + + if (msg->m_format == CDateTimeMessage::FORMAT_TIME) { + CTimePickerDialog timeDialog(msg); + retCode = timeDialog.DoModal(m_hWnd); + ret_time = timeDialog.GetTime(); + } else { + CDateTimePickerDialog dateTimeDialog(msg); + retCode = dateTimeDialog.DoModal(m_hWnd); + ret_time = dateTimeDialog.GetTime(); + } + + rho_rhodesapp_callDateTimeCallback( msg->m_callback, + retCode == IDOK ? (long )ret_time : 0, + msg->m_data, + retCode == IDOK ? 0 : 1); + delete msg; + + return 0; +} diff --git a/platform/wm/rhodes/emulator/MainWindowQt.h b/platform/wm/rhodes/emulator/MainWindowQt.h new file mode 100644 index 00000000000..e8dc55c2c71 --- /dev/null +++ b/platform/wm/rhodes/emulator/MainWindowQt.h @@ -0,0 +1,118 @@ +// MainWindow.h: Defines main window for this application. + +#pragma once + +#include "logging/RhoLog.h" +#include "common/RhoConf.h" +#include "common/RhodesApp.h" +#include "Alert.h" +#include "RhoNativeViewManagerWM.h" +#include "SyncStatusDlg.h" +#include "NativeToolbarQt.h" +#if defined(OS_WINDOWS) +#include "menubar.h" +#endif +#include "LogView.h" +#include "MainWindowProxy.h" +#include "MainWindowCallback.h" + +static UINT WM_TAKEPICTURE = ::RegisterWindowMessage(L"RHODES_WM_TAKEPICTURE"); +static UINT WM_SELECTPICTURE = ::RegisterWindowMessage(L"RHODES_WM_SELECTPICTURE"); +static UINT WM_TAKESIGNATURE = ::RegisterWindowMessage(L"RHODES_WM_TAKESIGNATURE"); +static UINT WM_ALERT_SHOW_POPUP = ::RegisterWindowMessage(L"RHODES_WM_ALERT_SHOW_POPUP"); +static UINT WM_ALERT_HIDE_POPUP = ::RegisterWindowMessage(L"RHODES_WM_ALERT_HIDE_POPUP"); +static UINT WM_DATETIME_PICKER = ::RegisterWindowMessage(L"RHODES_WM_DATETIME_PICKER"); +static UINT WM_EXECUTE_COMMAND = ::RegisterWindowMessage(L"RHODES_WM_EXECUTE_COMMAND"); +static UINT WM_EXECUTE_RUNNABLE = ::RegisterWindowMessage(L"RHODES_WM_EXECUTE_RUNNABLE"); + +#define ID_CUSTOM_MENU_ITEM_FIRST (WM_APP+3) +#define ID_CUSTOM_MENU_ITEM_LAST (ID_CUSTOM_MENU_ITEM_FIRST + (APP_MENU_ITEMS_MAX) - 1) +#define ID_CUSTOM_TOOLBAR_ITEM_FIRST (ID_CUSTOM_MENU_ITEM_LAST+1) +#define ID_CUSTOM_TOOLBAR_ITEM_LAST (ID_CUSTOM_TOOLBAR_ITEM_FIRST + 20 - 1) + +class CMainWindow : + public CWindowImpl >, + public IMainWindowCallback +{ + DEFINE_LOGCLASS; +public: + CMainWindow(); + ~CMainWindow(); + // IMainWindowCallback + virtual void updateSizeProperties(int width, int height); + virtual void onActivate(int active); + virtual void logEvent(const ::std::string& message); + virtual void createCustomMenu(void); + virtual void onCustomMenuItemCommand(int nItemPos); + // public methods: + void Navigate2(BSTR URL); + HWND Initialize(const wchar_t* title); + void MessageLoop(void); + void performOnUiThread(rho::common::IRhoRunnable* pTask); + CNativeToolbar& getToolbar(){ return m_toolbar; } + CMainWindowProxy &getProxy(){ return m_mainWindowProxy; } + HWND getWebViewHWND(); + + BEGIN_MSG_MAP(CMainWindow) + MESSAGE_HANDLER(WM_DESTROY, OnDestroy) + //MESSAGE_HANDLER(WM_ACTIVATE, OnActivate) + COMMAND_ID_HANDLER(IDM_EXIT, OnExitCommand) + COMMAND_ID_HANDLER(IDM_NAVIGATE_BACK, OnNavigateBackCommand) + COMMAND_ID_HANDLER(IDM_NAVIGATE_FORWARD, OnNavigateForwardCommand) + COMMAND_ID_HANDLER(IDM_SK1_EXIT, OnBackCommand) + COMMAND_ID_HANDLER(IDM_LOG,OnLogCommand) + COMMAND_ID_HANDLER(IDM_REFRESH, OnRefreshCommand) + COMMAND_ID_HANDLER(IDM_NAVIGATE, OnNavigateCommand) + MESSAGE_HANDLER(WM_TAKEPICTURE, OnTakePicture) + MESSAGE_HANDLER(WM_SELECTPICTURE, OnSelectPicture) + MESSAGE_HANDLER(WM_ALERT_SHOW_POPUP, OnAlertShowPopup) + MESSAGE_HANDLER(WM_ALERT_HIDE_POPUP, OnAlertHidePopup); + MESSAGE_HANDLER(WM_DATETIME_PICKER, OnDateTimePicker); + MESSAGE_HANDLER(WM_EXECUTE_COMMAND, OnExecuteCommand); + MESSAGE_HANDLER(WM_EXECUTE_RUNNABLE, OnExecuteRunnable); + END_MSG_MAP() + +private: + // WM_xxx handlers + LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled); + //LRESULT OnActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/); + + // WM_COMMAND handlers + LRESULT OnExitCommand(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnNavigateBackCommand(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnNavigateForwardCommand(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnBackCommand(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnLogCommand(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnRefreshCommand(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + LRESULT OnNavigateCommand(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/); + + LRESULT OnTakePicture(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/); + LRESULT OnSelectPicture(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/); + LRESULT OnAlertShowPopup (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/); + LRESULT OnAlertHidePopup (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/); + LRESULT OnDateTimePicker (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/); + LRESULT OnExecuteCommand (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/); + LRESULT OnExecuteRunnable (UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/); + +private: + CLogView m_logView; + CNativeToolbar m_toolbar; + CMainWindowProxy m_mainWindowProxy; + +private: + static int m_screenWidth; + static int m_screenHeight; + +public: + static int getScreenWidth() {return m_screenWidth;} + static int getScreenHeight() {return m_screenHeight;} + +private: + rho::Vector m_arAppMenuItems; + CAlertDialog *m_alertDialog; + CSyncStatusDlg m_SyncStatusDlg; +}; + +#if !defined(_WIN32_WCE) +HBITMAP SHLoadImageFile ( LPCTSTR pszFileName ); +#endif \ No newline at end of file diff --git a/platform/wm/rhodes/emulator/NativeToolbarQt.cpp b/platform/wm/rhodes/emulator/NativeToolbarQt.cpp new file mode 100644 index 00000000000..3710ca052ef --- /dev/null +++ b/platform/wm/rhodes/emulator/NativeToolbarQt.cpp @@ -0,0 +1,57 @@ +#include "stdafx.h" + +#include "NativeToolbarQt.h" +#include "common/rhoparams.h" +#include "MainWindowProxy.h" +#include "MainWindow.h" +#include "common/RhoFilePath.h" +#include "rubyext/WebView.h" +#undef null +#include +#include +#include + +extern CMainWindow& getAppWindow(); +IMPLEMENT_LOGCLASS(CNativeToolbar,"NativeToolbar"); + +using namespace rho; +using namespace rho::common; + +CNativeToolbar::CNativeToolbar(void) +{ +} + +CNativeToolbar::~CNativeToolbar(void) +{ +} + +void CNativeToolbar::OnFinalMessage(HWND /*hWnd*/) +{ + getAppWindow().getProxy().removeAllButtons(); +} + +/*static*/ CNativeToolbar& CNativeToolbar::getInstance() +{ + return getAppWindow().getToolbar(); +} + +void CNativeToolbar::createToolbar(rho_param *p) +{ + getAppWindow().getProxy().createToolbar(p); +} + + +void CNativeToolbar::removeToolbar() +{ + getAppWindow().getProxy().removeToolbar(); +} + +int CNativeToolbar::getHeight() +{ + return getAppWindow().getProxy().getHeight(); +} + +bool CNativeToolbar::isStarted() +{ + return getAppWindow().getProxy().isStarted(); +} diff --git a/platform/wm/rhodes/emulator/NativeToolbarQt.h b/platform/wm/rhodes/emulator/NativeToolbarQt.h new file mode 100644 index 00000000000..dade41e1572 --- /dev/null +++ b/platform/wm/rhodes/emulator/NativeToolbarQt.h @@ -0,0 +1,52 @@ +#pragma once + +#include "common/IRhoThreadImpl.h" +#include "ruby/ext/rho/rhoruby.h" + +#include +#include +#include +#include +#include + +class CNativeToolbar +{ + DEFINE_LOGCLASS; + +public: + static const int MIN_TOOLBAR_HEIGHT = 60; + +public: + class CCreateTask: public rho::common::IRhoRunnable + { + rho_param *m_param; + public: + CCreateTask(rho_param *p) : m_param(rho_param_dup(p)){ } + ~CCreateTask(){ rho_param_free(m_param); } + virtual void runObject(){ + CNativeToolbar::getInstance().createToolbar(m_param); + } + }; + class CRemoveTask: public rho::common::IRhoRunnable + { + public: + virtual void runObject(){ + CNativeToolbar::getInstance().removeToolbar(); + } + }; + +public: + CNativeToolbar(void); + ~CNativeToolbar(void); + + static CNativeToolbar& getInstance(); + + virtual void OnFinalMessage(HWND /*hWnd*/); + + int getHeight(); + bool isStarted(); + +private: + void createToolbar(rho_param *param); + void removeToolbar(); +}; diff --git a/platform/wm/rhodes/emulator/QtMainWindow.cpp b/platform/wm/rhodes/emulator/QtMainWindow.cpp new file mode 100644 index 00000000000..adca670cf9c --- /dev/null +++ b/platform/wm/rhodes/emulator/QtMainWindow.cpp @@ -0,0 +1,201 @@ +#pragma warning(disable:4996) +#include "QtMainWindow.h" +#include "ui_QtMainWindow.h" +#include "ExternalWebView.h" +#include +#include "common/RhoStd.h" +#include "common/RhodesApp.h" +#include "rubyext/WebView.h" +#undef null + +QtMainWindow::QtMainWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::QtMainWindow), + wi(new QWebInspector()), + cb(NULL) +{ + ui->setupUi(this); + this->ui->webView->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true); + this->ui->webView->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); + this->move(0,0); + this->ui->toolBar->hide(); + + // connecting WebInspector + wi->setWindowTitle("Web Inspector"); + wi->setPage(ui->webView->page()); + wi->move(416, this->geometry().y()); + wi->resize(850, 600); + wi->show(); +} + +QtMainWindow::~QtMainWindow() +{ + delete wi; + delete ui; +} + +void QtMainWindow::setCallback(IMainWindowCallback* callback) +{ + cb = callback; +} + +void QtMainWindow::hideEvent(QHideEvent *) +{ + if (cb) cb->onActivate(0); +} + +void QtMainWindow::showEvent(QShowEvent *) +{ + if (cb) cb->onActivate(1); +} + +void QtMainWindow::closeEvent(QCloseEvent *ce) +{ + wi->close(); + QMainWindow::closeEvent(ce); +} + +void QtMainWindow::resizeEvent(QResizeEvent *event) +{ + if (cb) + cb->updateSizeProperties(event->size().width(), event->size().height()); // ui->webView +} + +void QtMainWindow::on_actionBack_triggered() +{ + ui->webView->back(); +} + +void QtMainWindow::on_webView_linkClicked(const QUrl& url) +{ + QString sUrl = url.toString(); + if (sUrl.contains("rho_open_target=_blank")) { + if (cb) cb->logEvent("WebView: open external browser"); + ExternalWebView* externalWebView = new ExternalWebView(); + externalWebView->navigate(QUrl(sUrl.remove("rho_open_target=_blank"))); + externalWebView->show(); + externalWebView->activateWindow(); + } else + ui->webView->setUrl(url); +} + +void QtMainWindow::on_webView_loadStarted() +{ + if (cb) cb->logEvent("WebView: loading..."); +} + +void QtMainWindow::on_webView_loadFinished(bool ok) +{ + if (cb) cb->logEvent((ok?"WebView: loaded ":"WebView: failed ")); // +ui->webView->url().toString() +} + +void QtMainWindow::on_webView_urlChanged(QUrl url) +{ + if (cb) cb->logEvent("WebView: URL changed"); // url.toString() +} + +void QtMainWindow::on_menuMain_aboutToShow() +{ + if (cb) cb->createCustomMenu(); +} + +void QtMainWindow::navigate(QUrl url) +{ + ui->webView->setUrl(url); +} + +void QtMainWindow::GoBack(void) +{ + ui->webView->back(); +} + +void QtMainWindow::GoForward(void) +{ + ui->webView->forward(); +} + +void QtMainWindow::Refresh(void) +{ + ui->webView->reload(); +} + +void QtMainWindow::toolbarRemoveAllButtons() +{ + ui->toolBar->clear(); + ui->toolBarRight->clear(); +} + +void QtMainWindow::toolbarShow() +{ + ui->toolBar->show(); +} + +void QtMainWindow::toolbarHide() +{ + ui->toolBar->hide(); +} + +int QtMainWindow::toolbarGetHeight() +{ + return ui->toolBar->height(); +} + +void QtMainWindow::toolbarAddAction(const QString & text) +{ + ui->toolBar->addAction(text); +} + +void QtMainWindow::on_toolbarAction_triggered(bool checked) +{ + QObject* sender = QObject::sender(); + QAction* action; + if (sender && (action = dynamic_cast(sender))) { + rho::String strAction = action->data().toString().toStdString(); + if ( strcasecmp(strAction.c_str(), "forward") == 0 ) + rho_webview_navigate_forward(); + else + RHODESAPP().loadUrl(strAction); + } +} + +void QtMainWindow::toolbarAddAction(const QIcon & icon, const QString & text, const char* action, bool rightAlign) +{ + QAction* qAction = new QAction(icon, text, ui->toolBar); + qAction->setData(QVariant(action)); + QObject::connect(qAction, SIGNAL(triggered(bool)), this, SLOT(on_toolbarAction_triggered(bool)) ); + if (rightAlign) + ui->toolBarRight->insertAction( (ui->toolBarRight->actions().size() > 0 ? ui->toolBarRight->actions().last() : 0), qAction); + else + ui->toolBar->addAction(qAction); +} + +void QtMainWindow::toolbarAddSeparator() +{ + ui->toolBar->addSeparator(); +} + +void QtMainWindow::menuAddAction(const QString & text, int item) +{ + QAction* qAction = new QAction(text, ui->toolBar); + qAction->setData(QVariant(item)); + QObject::connect(qAction, SIGNAL(triggered(bool)), this, SLOT(on_menuAction_triggered(bool)) ); + ui->menuMain->addAction(qAction); +} + +void QtMainWindow::menuClear(void) +{ + ui->menuMain->clear(); +} + +void QtMainWindow::menuAddSeparator() +{ + ui->menuMain->addSeparator(); +} + +void QtMainWindow::on_menuAction_triggered(bool checked) +{ + QObject* sender = QObject::sender(); + QAction* action; + if (sender && (action = dynamic_cast(sender)) && cb) + cb->onCustomMenuItemCommand(action->data().toInt()); +} diff --git a/platform/wm/rhodes/emulator/QtMainWindow.h b/platform/wm/rhodes/emulator/QtMainWindow.h new file mode 100644 index 00000000000..fd67c3de3ff --- /dev/null +++ b/platform/wm/rhodes/emulator/QtMainWindow.h @@ -0,0 +1,61 @@ +#ifndef QTMAINWINDOW_H +#define QTMAINWINDOW_H + +#include +#include +#include +#include +#include "MainWindowCallback.h" +#include "common/IRhoThreadImpl.h" + +namespace Ui { + class QtMainWindow; +} + +class QtMainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit QtMainWindow(QWidget *parent = 0); + ~QtMainWindow(); + virtual void hideEvent(QHideEvent *); + virtual void showEvent(QShowEvent *); + virtual void closeEvent(QCloseEvent *); + void setCallback(IMainWindowCallback* callback); + // webview + void navigate(QUrl url); + void GoBack(void); + void GoForward(void); + void Refresh(void); + // toolbar + void toolbarRemoveAllButtons(void); + void toolbarShow(void); + void toolbarHide(void); + int toolbarGetHeight(void); + void toolbarAddAction(const QString & text); + void toolbarAddAction(const QIcon & icon, const QString & text, const char* action, bool rightAlign = false); + void toolbarAddSeparator(void); + // menu + void menuClear(void); + void menuAddAction(const QString & text, int item); + void menuAddSeparator(void); +private: + Ui::QtMainWindow *ui; + QWebInspector *wi; + IMainWindowCallback* cb; + +private slots: + void on_webView_urlChanged(QUrl ); + void on_webView_loadFinished(bool); + void on_webView_loadStarted(); + void on_webView_linkClicked(const QUrl&); + void on_actionBack_triggered(); + void on_toolbarAction_triggered(bool); + void on_menuAction_triggered(bool); + void on_menuMain_aboutToShow(); +protected: + void resizeEvent(QResizeEvent *); +}; + +#endif // QTMAINWINDOW_H diff --git a/platform/wm/rhodes/emulator/QtMainWindow.ui b/platform/wm/rhodes/emulator/QtMainWindow.ui new file mode 100644 index 00000000000..8221dcc502a --- /dev/null +++ b/platform/wm/rhodes/emulator/QtMainWindow.ui @@ -0,0 +1,122 @@ + + + QtMainWindow + + + + 0 + 0 + 400 + 600 + + + + MainWindow + + + + + + + + 0 + + + 0 + + + + + + about:blank + + + + + + + + + + 0 + 0 + 400 + 21 + + + + + Main + + + + + Navigate + + + + + + + + + toolBar + + + + + + false + + + Qt::BottomToolBarArea + + + false + + + BottomToolBarArea + + + false + + + + + toolBarRight + + + Qt::RightToLeft + + + false + + + Qt::BottomToolBarArea + + + false + + + BottomToolBarArea + + + false + + + + + Back + + + + + + QWebView + QWidget +
QtWebKit/QWebView
+
+
+ + +
diff --git a/platform/wm/rhodes/rho/rubyext/NativeToolbar.cpp b/platform/wm/rhodes/rho/rubyext/NativeToolbar.cpp index c414e7690c3..234673ce454 100644 --- a/platform/wm/rhodes/rho/rubyext/NativeToolbar.cpp +++ b/platform/wm/rhodes/rho/rubyext/NativeToolbar.cpp @@ -11,6 +11,8 @@ #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif +extern CMainWindow& getAppWindow(); + IMPLEMENT_LOGCLASS(CNativeToolbar,"NativeToolbar"); extern "C" int rho_wmsys_has_touchscreen(); diff --git a/platform/wm/rhodes/rho/rubyext/NativeToolbarExt.cpp b/platform/wm/rhodes/rho/rubyext/NativeToolbarExt.cpp index 4fb6170b786..d201db21ae9 100644 --- a/platform/wm/rhodes/rho/rubyext/NativeToolbarExt.cpp +++ b/platform/wm/rhodes/rho/rubyext/NativeToolbarExt.cpp @@ -1,7 +1,10 @@ #include "stdafx.h" +#include "MainWindow.h" #include "NativeToolbarExt.h" +extern CMainWindow& getAppWindow(); + extern "C" { void remove_native_toolbar(); diff --git a/platform/wm/rhodes/rho/rubyext/NativeToolbarExt.h b/platform/wm/rhodes/rho/rubyext/NativeToolbarExt.h index d5f5ca6a870..64361a0a5a4 100644 --- a/platform/wm/rhodes/rho/rubyext/NativeToolbarExt.h +++ b/platform/wm/rhodes/rho/rubyext/NativeToolbarExt.h @@ -1,11 +1,6 @@ #pragma once -#include "NativeToolbar.h" -#include "MainWindow.h" - #define TOOLBAR_TYPE 0 #define TABBAR_TYPE 1 #define NOBAR_TYPE 2 #define VTABBAR_TYPE 3 - -extern CMainWindow& getAppWindow(); diff --git a/platform/wm/rhodes/rho/rubyext/SystemImpl.cpp b/platform/wm/rhodes/rho/rubyext/SystemImpl.cpp index 7b409ca861b..022b8e1b11f 100644 --- a/platform/wm/rhodes/rho/rubyext/SystemImpl.cpp +++ b/platform/wm/rhodes/rho/rubyext/SystemImpl.cpp @@ -4,6 +4,10 @@ #include "common/StringConverter.h" #include "common/RhoFilePath.h" #include "ruby/ext/rho/rhoruby.h" +#ifdef RHODES_EMULATOR +#undef null +#include +#endif #include "MainWindow.h" #if defined( OS_WINCE ) && !defined( OS_PLATFORM_CE ) @@ -327,6 +331,7 @@ static void toHexString(int i, String& strRes, int radix) strRes += (buf+f+1); } +#ifndef RHODES_EMULATOR int get_msie_version(rho::String& msieVer) // Return codes are as follows: // 0 : Success @@ -368,14 +373,19 @@ int get_msie_version(rho::String& msieVer) #endif return 0; } +#endif int rho_sysimpl_get_property(char* szPropName, VALUE* resValue) { if (strcasecmp("webview",szPropName) == 0) { +#ifdef RHODES_EMULATOR + *resValue = rho_ruby_create_string("WEBKIT/" QTWEBKIT_VERSION_STR); +#else rho::String msieVer = "IE"; get_msie_version(msieVer); *resValue = rho_ruby_create_string(msieVer.c_str()); +#endif return 1; } diff --git a/platform/wm/rhodes/rhodes.vcproj b/platform/wm/rhodes/rhodes.vcproj index 45019071882..4c19841e1d6 100644 --- a/platform/wm/rhodes/rhodes.vcproj +++ b/platform/wm/rhodes/rhodes.vcproj @@ -229,8 +229,8 @@
+ + + + + + - - @@ -2585,6 +2598,22 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -109,8 +109,8 @@ @@ -324,8 +324,8 @@ @@ -397,8 +397,8 @@ @@ -609,8 +609,8 @@ @@ -684,8 +684,8 @@ @@ -759,8 +759,8 @@ @@ -835,8 +835,8 @@ @@ -862,6 +862,7 @@ PreprocessorDefinitions="_DEBUG;DEBUG;WIN32;_WINDOWS;_LIB;BUFSIZ=512;TLS_OUT_OF_INDEXES=0xFFFFFFFF;FILENAME_MAX=MAX_PATH;STATIC_LINKED" MinimalRebuild="true" RuntimeLibrary="1" + TreatWChar_tAsBuiltInType="false" UsePrecompiledHeader="0" WarningLevel="0" DebugInformationFormat="3" @@ -901,8 +902,8 @@ @@ -975,8 +976,8 @@ @@ -1049,8 +1050,8 @@ @@ -1124,8 +1125,8 @@ @@ -1150,6 +1151,7 @@ AdditionalIncludeDirectories="..\..\shared\ruby\.;..\..\shared\ruby\include;..\..\shared\ruby\win32;..\..\shared\ruby\generated;..\..\shared" PreprocessorDefinitions="_NDEBUG;NDEBUG;WIN32;_WINDOWS;_LIB;BUFSIZ=512;TLS_OUT_OF_INDEXES=0xFFFFFFFF;FILENAME_MAX=MAX_PATH;STATIC_LINKED" RuntimeLibrary="0" + TreatWChar_tAsBuiltInType="false" UsePrecompiledHeader="0" WarningLevel="0" DebugInformationFormat="3" diff --git a/platform/wm/shttpd/shttpd.vcproj b/platform/wm/shttpd/shttpd.vcproj index 8382ae79a43..4733f8aefcc 100644 --- a/platform/wm/shttpd/shttpd.vcproj +++ b/platform/wm/shttpd/shttpd.vcproj @@ -29,8 +29,8 @@ @@ -394,8 +394,8 @@ diff --git a/platform/wm/sqlite3/sqlite3.vcproj b/platform/wm/sqlite3/sqlite3.vcproj index 5797674615e..80e7e9d1937 100644 --- a/platform/wm/sqlite3/sqlite3.vcproj +++ b/platform/wm/sqlite3/sqlite3.vcproj @@ -35,8 +35,8 @@ @@ -109,8 +109,8 @@ @@ -324,8 +324,8 @@ @@ -397,8 +397,8 @@ @@ -609,8 +609,8 @@ @@ -684,8 +684,8 @@ @@ -759,8 +759,8 @@ @@ -835,8 +835,8 @@ @@ -862,6 +862,7 @@ PreprocessorDefinitions="_DEBUG;DEBUG;WIN32;_WINDOWS;_LIB;_UNICODE;UNICODE" MinimalRebuild="true" RuntimeLibrary="1" + TreatWChar_tAsBuiltInType="false" UsePrecompiledHeader="0" WarningLevel="0" DebugInformationFormat="3" @@ -901,8 +902,8 @@ @@ -975,8 +976,8 @@ @@ -1049,8 +1050,8 @@ @@ -1124,8 +1125,8 @@ @@ -1150,6 +1151,7 @@ AdditionalIncludeDirectories="../../shared" PreprocessorDefinitions="_NDEBUG;NDEBUG;WIN32;_WINDOWS;_LIB;_UNICODE;UNICODE" RuntimeLibrary="0" + TreatWChar_tAsBuiltInType="false" UsePrecompiledHeader="0" WarningLevel="0" DebugInformationFormat="3" diff --git a/platform/wm/syncengine/syncengine.vcproj b/platform/wm/syncengine/syncengine.vcproj index 4278b835033..469567a7000 100644 --- a/platform/wm/syncengine/syncengine.vcproj +++ b/platform/wm/syncengine/syncengine.vcproj @@ -35,8 +35,8 @@ @@ -109,8 +109,8 @@ @@ -324,8 +324,8 @@ @@ -397,8 +397,8 @@ @@ -609,8 +609,8 @@ @@ -684,8 +684,8 @@ @@ -759,8 +759,8 @@ @@ -835,8 +835,8 @@ @@ -862,6 +862,7 @@ PreprocessorDefinitions="_DEBUG;DEBUG;WIN32;_WINDOWS;_LIB;_UNICODE;UNICODE" MinimalRebuild="true" RuntimeLibrary="1" + TreatWChar_tAsBuiltInType="false" UsePrecompiledHeader="0" WarningLevel="3" DebugInformationFormat="3" @@ -901,8 +902,8 @@ @@ -975,8 +976,8 @@ @@ -1049,8 +1050,8 @@ @@ -1124,8 +1125,8 @@ @@ -1150,6 +1151,7 @@ AdditionalIncludeDirectories="..\..\shared\json;..\..\shared" PreprocessorDefinitions="_NDEBUG;NDEBUG;WIN32;_WINDOWS;_LIB;_UNICODE;UNICODE" RuntimeLibrary="0" + TreatWChar_tAsBuiltInType="false" UsePrecompiledHeader="0" WarningLevel="3" DebugInformationFormat="3"