diff options
Diffstat (limited to 'src/android/jar/src')
6 files changed, 282 insertions, 491 deletions
diff --git a/src/android/jar/src/org/qtproject/qt5/android/CursorHandle.java b/src/android/jar/src/org/qtproject/qt5/android/CursorHandle.java index 4f2c06644d..788a5c2b3d 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/CursorHandle.java +++ b/src/android/jar/src/org/qtproject/qt5/android/CursorHandle.java @@ -142,7 +142,6 @@ public class CursorHandle implements ViewTreeObserver.OnPreDrawListener m_cursorView = new CursorView(context, this); m_cursorView.setImageDrawable(drawable); - // m_layout.addView(m_cursorView); m_popup = new PopupWindow(context, null, android.R.attr.textSelectHandleWindowStyle); m_popup.setSplitTouchEnabled(true); @@ -185,6 +184,14 @@ public class CursorHandle implements ViewTreeObserver.OnPreDrawListener m_posY = y; } + public int bottom() + { + initOverlay(); + final int[] location = new int[2]; + m_cursorView.getLocationOnScreen(location); + return location[1] + m_cursorView.getHeight(); + } + public void hide() { if (m_popup != null) { m_popup.dismiss(); diff --git a/src/android/jar/src/org/qtproject/qt5/android/EditContextView.java b/src/android/jar/src/org/qtproject/qt5/android/EditContextView.java new file mode 100644 index 0000000000..6d9987ca2a --- /dev/null +++ b/src/android/jar/src/org/qtproject/qt5/android/EditContextView.java @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2018 BogDan Vatra <bogdan@kde.org> +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Android port of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +package org.qtproject.qt5.android; + + +import android.content.Context; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.R; + +import java.util.HashMap; + +public class EditContextView extends LinearLayout implements View.OnClickListener +{ + public static final int CUT_BUTTON = 1 << 0; + public static final int COPY_BUTTON = 1 << 1; + public static final int PASTE_BUTTON = 1 << 2; + public static final int SALL_BUTTON = 1 << 3; + + HashMap<Integer, ContextButton> m_buttons = new HashMap<Integer, ContextButton>(4); + OnClickListener m_onClickListener; + + public interface OnClickListener + { + void contextButtonClicked(int buttonId); + } + + private class ContextButton extends TextView + { + public int m_buttonId; + public ContextButton(Context context, int stringId) { + super(context); + m_buttonId = stringId; + setText(stringId); + setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT)); + setGravity(Gravity.CENTER); + setTextColor(getResources().getColor(R.color.widget_edittext_dark)); + EditContextView.this.setBackground(getResources().getDrawable(R.drawable.editbox_background_normal)); + float scale = getResources().getDisplayMetrics().density; + int hPadding = (int)(16 * scale + 0.5f); + int vPadding = (int)(8 * scale + 0.5f); + setPadding(hPadding, vPadding, hPadding, vPadding); + setOnClickListener(EditContextView.this); + } + } + + @Override + public void onClick(View v) + { + ContextButton button = (ContextButton)v; + m_onClickListener.contextButtonClicked(button.m_buttonId); + } + + void addButton(int id) + { + ContextButton button = new ContextButton(getContext(), id); + m_buttons.put(id, button); + addView(button); + } + + public void updateButtons(int buttonsLayout) + { + m_buttons.get(R.string.cut).setVisibility((buttonsLayout & CUT_BUTTON) != 0 ? View.VISIBLE : View.GONE); + m_buttons.get(R.string.copy).setVisibility((buttonsLayout & COPY_BUTTON) != 0 ? View.VISIBLE : View.GONE); + m_buttons.get(R.string.paste).setVisibility((buttonsLayout & PASTE_BUTTON) != 0 ? View.VISIBLE : View.GONE); + m_buttons.get(R.string.selectAll).setVisibility((buttonsLayout & SALL_BUTTON) != 0 ? View.VISIBLE : View.GONE); + } + + public EditContextView(Context context, OnClickListener onClickListener) { + super(context); + m_onClickListener = onClickListener; + setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + + addButton(R.string.cut); + addButton(R.string.copy); + addButton(R.string.paste); + addButton(R.string.selectAll); + } +} diff --git a/src/android/jar/src/org/qtproject/qt5/android/EditMenu.java b/src/android/jar/src/org/qtproject/qt5/android/EditMenu.java deleted file mode 100644 index afe7797914..0000000000 --- a/src/android/jar/src/org/qtproject/qt5/android/EditMenu.java +++ /dev/null @@ -1,142 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com> -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the Android port of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -package org.qtproject.qt5.android; - -import android.view.ActionMode; -import android.view.ActionMode.Callback; -import android.view.Menu; -import android.view.MenuItem; -import android.app.Activity; -import android.content.Context; -import android.content.res.TypedArray; - -/** - * The edit menu actions (when there is selection) - */ -class EditMenu implements ActionMode.Callback { - - private final Activity m_activity; - private ActionMode m_actionMode; - - public EditMenu(Activity activity) { - m_activity = activity; - } - - @Override - public boolean onCreateActionMode(ActionMode mode, Menu menu) { - mode.setTitle(null); - mode.setSubtitle(null); - mode.setTitleOptionalHint(true); - - Context context = m_activity; - int[] attrs = { - android.R.attr.actionModeSelectAllDrawable, android.R.attr.actionModeCutDrawable, - android.R.attr.actionModeCopyDrawable, android.R.attr.actionModePasteDrawable - }; - TypedArray a = context.getTheme().obtainStyledAttributes(attrs); - - menu.add(Menu.NONE, android.R.id.selectAll, Menu.NONE, android.R.string.selectAll) - .setIcon(a.getResourceId(0, 0)) - .setAlphabeticShortcut('a') - .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT); - - menu.add(Menu.NONE, android.R.id.cut, Menu.NONE, android.R.string.cut) - .setIcon(a.getResourceId(1, 0)) - .setAlphabeticShortcut('x') - .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT); - - menu.add(Menu.NONE, android.R.id.copy, Menu.NONE, android.R.string.copy) - .setIcon(a.getResourceId(2, 0)) - .setAlphabeticShortcut('c') - .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT); - - menu.add(Menu.NONE, android.R.id.paste, Menu.NONE, android.R.string.paste) - .setIcon(a.getResourceId(3, 0)) - .setAlphabeticShortcut('v') - .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT); - - return true; - } - - @Override - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - return true; - } - - @Override - public void onDestroyActionMode(ActionMode mode) { - m_actionMode = null; - } - - @Override - public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - - switch (item.getItemId()) { - case android.R.id.cut: - return QtNativeInputConnection.cut(); - case android.R.id.copy: - return QtNativeInputConnection.copy(); - case android.R.id.paste: - return QtNativeInputConnection.paste(); - case android.R.id.selectAll: - return QtNativeInputConnection.selectAll(); - } - return false; - } - - public void hide() - { - if (m_actionMode != null) { - m_actionMode.finish(); - } - } - - public void show() - { - if (m_actionMode == null) { - m_actionMode = m_activity.startActionMode(this); - } - } - - public boolean isShown() - { - return m_actionMode != null; - } -} diff --git a/src/android/jar/src/org/qtproject/qt5/android/EditPopupMenu.java b/src/android/jar/src/org/qtproject/qt5/android/EditPopupMenu.java index 246be1aeb2..d065cd8549 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/EditPopupMenu.java +++ b/src/android/jar/src/org/qtproject/qt5/android/EditPopupMenu.java @@ -1,5 +1,6 @@ /**************************************************************************** ** +** Copyright (C) 2018 BogDan Vatra <bogdan@kde.org> ** Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com> ** Contact: http://www.qt.io/licensing/ ** @@ -55,59 +56,51 @@ import android.view.ViewTreeObserver; import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.view.ViewGroup; +import android.R; // Helper class that manages a cursor or selection handle -public class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, OnClickListener +public class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, EditContextView.OnClickListener { private View m_layout = null; - private View m_view = null; + private EditContextView m_view = null; private PopupWindow m_popup = null; - private Activity m_activity; private int m_posX; private int m_posY; + private int m_buttons; - public EditPopupMenu(Activity activity, View layout) { - m_activity = activity; + public EditPopupMenu(Activity activity, View layout) + { + m_view = new EditContextView(activity, this); m_layout = layout; } - private boolean initOverlay(){ - if (m_popup == null){ - Context context = m_layout.getContext(); - int[] attrs = { android.R.attr.textEditPasteWindowLayout }; - TypedArray a = context.getTheme().obtainStyledAttributes(attrs); - final int layout = a.getResourceId(0, 0); - LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - m_view = inflater.inflate(layout, null); - - final int size = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); - m_view.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.WRAP_CONTENT)); - m_view.measure(size, size); - m_view.setOnClickListener(this); - - m_popup = new PopupWindow(context, null, android.R.attr.textSelectHandleWindowStyle); - m_popup.setSplitTouchEnabled(true); - m_popup.setClippingEnabled(false); - m_popup.setContentView(m_view); - m_popup.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT); - m_popup.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); - - m_layout.getViewTreeObserver().addOnPreDrawListener(this); - } - return true; + private void initOverlay() + { + if (m_popup != null) + return; + + Context context = m_layout.getContext(); + m_popup = new PopupWindow(context, null, android.R.attr.textSelectHandleWindowStyle); + m_popup.setSplitTouchEnabled(true); + m_popup.setClippingEnabled(false); + m_popup.setContentView(m_view); + m_popup.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT); + m_popup.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); + + m_layout.getViewTreeObserver().addOnPreDrawListener(this); } public int getHeight() { - initOverlay(); return m_view.getHeight(); } // Show the handle at a given position (or move it if it is already shown) - public void setPosition(final int x, final int y){ + public void setPosition(final int x, final int y, final int buttons) + { initOverlay(); + m_view.updateButtons(buttons); final int[] location = new int[2]; m_layout.getLocationOnScreen(location); @@ -115,9 +108,12 @@ public class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, OnClic int y2 = y + location[1]; x2 -= m_view.getWidth() / 2 ; + + if (m_layout.getWidth() < x + m_view.getWidth() / 2) + x2 = m_layout.getWidth() - m_view.getWidth(); + if (x2 < 0) x2 = 0; - y2 -= m_view.getHeight(); if (m_popup.isShowing()) m_popup.update(x2, y2, -1, -1); @@ -126,12 +122,13 @@ public class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, OnClic m_posX = x; m_posY = y; - + m_buttons = buttons; } public void hide() { if (m_popup != null) { m_popup.dismiss(); + m_popup = null; } } @@ -141,15 +138,27 @@ public class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, OnClic // For example if the keyboard appears. // Adjust the position of the handle accordingly if (m_popup != null && m_popup.isShowing()) - setPosition(m_posX, m_posY); + setPosition(m_posX, m_posY, m_buttons); return true; } @Override - public void onClick(View v) { - QtNativeInputConnection.paste(); + public void contextButtonClicked(int buttonId) { + switch (buttonId) { + case R.string.cut: + QtNativeInputConnection.cut(); + break; + case R.string.copy: + QtNativeInputConnection.copy(); + break; + case R.string.paste: + QtNativeInputConnection.paste(); + break; + case R.string.selectAll: + QtNativeInputConnection.selectAll(); + break; + } hide(); } } - diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index fa7508921d..8f218d34f0 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -140,7 +140,6 @@ public class QtActivityDelegate private QtEditText m_editText = null; private InputMethodManager m_imm = null; private boolean m_quitApp = true; - private Process m_debuggerProcess = null; // debugger process private View m_dummyView = null; private boolean m_keyboardIsVisible = false; public boolean m_backKeyPressedSent = false; @@ -151,7 +150,6 @@ public class QtActivityDelegate private CursorHandle m_cursorHandle; private CursorHandle m_leftSelectionHandle; private CursorHandle m_rightSelectionHandle; - private EditMenu m_editMenu; private EditPopupMenu m_editPopupMenu; public void setFullScreen(boolean enterFullScreen) @@ -484,77 +482,87 @@ public class QtActivityDelegate } // Values coming from QAndroidInputContext::CursorHandleShowMode - private static final int CursorHandleNotShown = 0; - private static final int CursorHandleShowNormal = 1; - private static final int CursorHandleShowSelection = 2; - private static final int CursorHandleShowPopup = 3; + private static final int CursorHandleNotShown = 0; + private static final int CursorHandleShowNormal = 1; + private static final int CursorHandleShowSelection = 2; + private static final int CursorHandleShowEdit = 0x100; /* called from the C++ code when the position of the cursor or selection handles needs to be adjusted. mode is one of QAndroidInputContext::CursorHandleShowMode */ - public void updateHandles(int mode, int x1, int y1, int x2, int y2, boolean rtl) + public void updateHandles(int mode, int editX, int editY, int editButtons, int x1, int y1, int x2, int y2, boolean rtl) { - if (mode == CursorHandleNotShown) { - if (m_cursorHandle != null) - m_cursorHandle.hide(); - if (m_rightSelectionHandle != null) { - m_rightSelectionHandle.hide(); - m_leftSelectionHandle.hide(); - m_rightSelectionHandle = null; - m_leftSelectionHandle = null; - } - if (m_editMenu != null) - m_editMenu.hide(); - if (m_editPopupMenu != null) + switch (mode & 0xff) + { + case CursorHandleNotShown: + if (m_cursorHandle != null) { + m_cursorHandle.hide(); + m_cursorHandle = null; + } + if (m_rightSelectionHandle != null) { + m_rightSelectionHandle.hide(); + m_leftSelectionHandle.hide(); + m_rightSelectionHandle = null; + m_leftSelectionHandle = null; + } m_editPopupMenu.hide(); - } else if (mode == CursorHandleShowNormal || mode == CursorHandleShowPopup) { - if (m_cursorHandle == null) { - m_cursorHandle = new CursorHandle(m_activity, m_layout, QtNative.IdCursorHandle, - android.R.attr.textSelectHandle, false); - } - m_cursorHandle.setPosition(x1, y1); - if (m_rightSelectionHandle != null) { - m_rightSelectionHandle.hide(); - m_leftSelectionHandle.hide(); - m_rightSelectionHandle = null; - m_leftSelectionHandle = null; - } - } else if (mode == CursorHandleShowSelection) { - if (m_rightSelectionHandle == null) { - m_leftSelectionHandle = new CursorHandle(m_activity, m_layout, QtNative.IdLeftHandle, - !rtl ? android.R.attr.textSelectHandleLeft : - android.R.attr.textSelectHandleRight, - rtl); - m_rightSelectionHandle = new CursorHandle(m_activity, m_layout, QtNative.IdRightHandle, - !rtl ? android.R.attr.textSelectHandleRight : - android.R.attr.textSelectHandleLeft, - rtl); - } - m_leftSelectionHandle.setPosition(x1,y1); - m_rightSelectionHandle.setPosition(x2,y2); - if (m_cursorHandle != null) - m_cursorHandle.hide(); - - if (m_editMenu == null) - m_editMenu = new EditMenu(m_activity); - m_editMenu.show(); + break; + + case CursorHandleShowNormal: + if (m_cursorHandle == null) { + m_cursorHandle = new CursorHandle(m_activity, m_layout, QtNative.IdCursorHandle, + android.R.attr.textSelectHandle, false); + } + m_cursorHandle.setPosition(x1, y1); + if (m_rightSelectionHandle != null) { + m_rightSelectionHandle.hide(); + m_leftSelectionHandle.hide(); + m_rightSelectionHandle = null; + m_leftSelectionHandle = null; + } + break; + + case CursorHandleShowSelection: + if (m_rightSelectionHandle == null) { + m_leftSelectionHandle = new CursorHandle(m_activity, m_layout, QtNative.IdLeftHandle, + !rtl ? android.R.attr.textSelectHandleLeft : + android.R.attr.textSelectHandleRight, + rtl); + m_rightSelectionHandle = new CursorHandle(m_activity, m_layout, QtNative.IdRightHandle, + !rtl ? android.R.attr.textSelectHandleRight : + android.R.attr.textSelectHandleLeft, + rtl); + } + m_leftSelectionHandle.setPosition(x1,y1); + m_rightSelectionHandle.setPosition(x2,y2); + if (m_cursorHandle != null) { + m_cursorHandle.hide(); + m_cursorHandle = null; + } + mode |= CursorHandleShowEdit; + break; } - // show the edit popup menu - if (mode == CursorHandleShowPopup && (m_editMenu == null || !m_editMenu.isShown()) - && QtNative.hasClipboardText()) { - if (m_editPopupMenu == null) - m_editPopupMenu = new EditPopupMenu(m_activity, m_layout); - if (y2 < m_editPopupMenu.getHeight()) { - // If the popup cannot be shown over the text, it must be shown under the anchors - y2 = y1 + 2 * m_editPopupMenu.getHeight(); + if (QtNative.hasClipboardText()) + editButtons |= EditContextView.PASTE_BUTTON; + else + editButtons &= ~EditContextView.PASTE_BUTTON; + + if ((mode & CursorHandleShowEdit) == CursorHandleShowEdit && editButtons != 0) { + editY -= m_editPopupMenu.getHeight(); + if (editY < 0) { + if (m_cursorHandle != null) + editY = m_cursorHandle.bottom(); + else if (m_leftSelectionHandle != null && m_rightSelectionHandle != null) + editY = Math.max(m_leftSelectionHandle.bottom(), m_rightSelectionHandle.bottom()); + else + return; } - m_editPopupMenu.setPosition(x2, y2); - } else if (m_editPopupMenu != null) { + m_editPopupMenu.setPosition(editX, editY, editButtons); + } else { m_editPopupMenu.hide(); } - } public boolean loadApplication(Activity activity, ClassLoader classLoader, Bundle loaderParams) @@ -658,70 +666,6 @@ public class QtActivityDelegate return true; } - public static void debugLog(String msg) - { - Log.i(QtNative.QtTAG, "DEBUGGER: " + msg); - } - - private class DebugWaitRunnable implements Runnable { - - public DebugWaitRunnable(String pingPongSocket) throws IOException { - socket = new LocalServerSocket(pingPongSocket); - } - - public boolean wasFailure; - private LocalServerSocket socket; - - public void run() { - final int napTime = 200; // milliseconds between file accesses - final int timeOut = 30000; // ms until we give up on ping and pong - final int maxAttempts = timeOut / napTime; - - DataOutputStream outToClient = null; - try { - LocalSocket connectionFromClient = socket.accept(); - debugLog("Debug socket accepted"); - BufferedReader inFromClient = - new BufferedReader(new InputStreamReader(connectionFromClient.getInputStream())); - outToClient = new DataOutputStream(connectionFromClient.getOutputStream()); - outToClient.writeBytes("" + android.os.Process.myPid()); - - for (int i = 0; i < maxAttempts; i++) { - String clientData = inFromClient.readLine(); - debugLog("Incoming socket " + clientData); - if (!clientData.isEmpty()) - break; - - if (connectionFromClient.isClosed()) { - wasFailure = true; - break; - } - Thread.sleep(napTime); - } - } catch (IOException ioEx) { - ioEx.printStackTrace(); - wasFailure = true; - Log.e(QtNative.QtTAG,"Can't start debugger" + ioEx.getMessage()); - } catch (InterruptedException interruptEx) { - wasFailure = true; - Log.e(QtNative.QtTAG,"Can't start debugger" + interruptEx.getMessage()); - } finally { - try { - if (outToClient != null) - outToClient.close(); - } catch (IOException ignored) { } - } - } - - public void shutdown() throws IOException - { - wasFailure = true; - try { - socket.close(); - } catch (IOException ignored) { } - } - }; - public boolean startApplication() { // start application @@ -730,170 +674,6 @@ public class QtActivityDelegate Bundle extras = m_activity.getIntent().getExtras(); if (extras != null) { try { - final String dc = "--Added-by-androiddeployqt--/debugger.command"; - String debuggerCommand = - new BufferedReader(new InputStreamReader(m_activity.getAssets().open(dc))).readLine(); - if ( /*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0 - &&*/ extras.containsKey("debug_ping") - && extras.getString("debug_ping").equals("true")) { - try { - String packagePath = - m_activity.getPackageManager().getApplicationInfo(m_activity.getPackageName(), - PackageManager.GET_CONFIGURATIONS).dataDir + "/"; - - debugLog("extra parameters: " + extras); - String packageName = m_activity.getPackageName(); - String pingFile = extras.getString("ping_file"); - String pongFile = extras.getString("pong_file"); - String gdbserverSocket = extras.getString("gdbserver_socket"); - String gdbserverCommand = packagePath + debuggerCommand + gdbserverSocket; - String pingSocket = extras.getString("ping_socket"); - boolean usePing = pingFile != null; - boolean usePong = pongFile != null; - boolean useSocket = gdbserverSocket != null; - boolean usePingSocket = pingSocket != null; - int napTime = 200; // milliseconds between file accesses - int timeOut = 30000; // ms until we give up on ping and pong - int maxAttempts = timeOut / napTime; - - if (gdbserverSocket != null) { - debugLog("removing gdb socket " + gdbserverSocket); - new File(gdbserverSocket).delete(); - } - - if (usePing) { - debugLog("removing ping file " + pingFile); - File ping = new File(pingFile); - if (ping.exists()) { - if (!ping.delete()) - debugLog("ping file cannot be deleted"); - } - } - - if (usePong) { - debugLog("removing pong file " + pongFile); - File pong = new File(pongFile); - if (pong.exists()) { - if (!pong.delete()) - debugLog("pong file cannot be deleted"); - } - } - - debugLog("starting " + gdbserverCommand); - m_debuggerProcess = Runtime.getRuntime().exec(gdbserverCommand); - debugLog("gdbserver started"); - - if (useSocket) { - int i; - for (i = 0; i < maxAttempts; ++i) { - debugLog("waiting for socket at " + gdbserverSocket + ", attempt " + i); - File file = new File(gdbserverSocket); - if (file.exists()) { - file.setReadable(true, false); - file.setWritable(true, false); - file.setExecutable(true, false); - break; - } - Thread.sleep(napTime); - } - - if (i == maxAttempts) { - debugLog("time out when waiting for debug socket"); - return false; - } - - debugLog("socket ok"); - } else { - debugLog("socket not used"); - } - - if (usePingSocket) { - DebugWaitRunnable runnable = new DebugWaitRunnable(pingSocket); - Thread waitThread = new Thread(runnable); - waitThread.start(); - - int i; - for (i = 0; i < maxAttempts && waitThread.isAlive(); ++i) { - debugLog("Waiting for debug socket connect"); - debugLog("go to sleep"); - Thread.sleep(napTime); - } - - if (i == maxAttempts) { - debugLog("time out when waiting for ping socket"); - runnable.shutdown(); - return false; - } - - if (runnable.wasFailure) { - debugLog("Could not connect to debug client"); - return false; - } else { - debugLog("Got pid acknowledgment"); - } - } - - if (usePing) { - // Tell we are ready. - debugLog("writing ping at " + pingFile); - FileWriter writer = new FileWriter(pingFile); - writer.write("" + android.os.Process.myPid()); - writer.close(); - File file = new File(pingFile); - file.setReadable(true, false); - file.setWritable(true, false); - file.setExecutable(true, false); - debugLog("wrote ping"); - } else { - debugLog("ping not requested"); - } - - // Wait until other side is ready. - if (usePong) { - int i; - for (i = 0; i < maxAttempts; ++i) { - debugLog("waiting for pong at " + pongFile + ", attempt " + i); - File file = new File(pongFile); - if (file.exists()) { - file.delete(); - break; - } - debugLog("go to sleep"); - Thread.sleep(napTime); - } - debugLog("Removing pingFile " + pingFile); - new File(pingFile).delete(); - - if (i == maxAttempts) { - debugLog("time out when waiting for pong file"); - return false; - } - - debugLog("got pong " + pongFile); - } else { - debugLog("pong not requested"); - } - - } catch (IOException ioe) { - ioe.printStackTrace(); - } catch (SecurityException se) { - se.printStackTrace(); - } - } - - if (/*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0 - &&*/ extras.containsKey("qml_debug") - && extras.getString("qml_debug").equals("true")) { - String qmljsdebugger; - if (extras.containsKey("qmljsdebugger")) { - qmljsdebugger = extras.getString("qmljsdebugger"); - qmljsdebugger.replaceAll("\\s", ""); // remove whitespace for security - } else { - qmljsdebugger = "port:3768"; - } - m_applicationParameters += "\t-qmljsdebugger=" + qmljsdebugger; - } - if (extras.containsKey("extraenvvars")) { try { m_environmentVariables += "\t" + new String(Base64.decode(extras.getString("extraenvvars"), Base64.DEFAULT), "UTF-8"); @@ -1008,6 +788,7 @@ public class QtActivityDelegate return true; } }); + m_editPopupMenu = new EditPopupMenu(m_activity, m_layout); } public void hideSplashScreen() @@ -1081,8 +862,6 @@ public class QtActivityDelegate if (m_quitApp) { QtNative.terminateQt(); QtNative.setActivity(null, null); - if (m_debuggerProcess != null) - m_debuggerProcess.destroy(); QtNative.m_qtThread.exit(); System.exit(0); } diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java index 3db3453263..61f6afe85d 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java @@ -469,10 +469,11 @@ public class QtNative case MotionEvent.TOOL_TYPE_ERASER: pointerType = 3; // QTabletEvent::Eraser break; - // TODO TOOL_TYPE_MOUSE } - if (m_tabletEventSupported && pointerType != 0) { + if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) { + sendMouseEvent(event, id); + } else if (m_tabletEventSupported && pointerType != 0) { tabletEvent(id, event.getDeviceId(), event.getEventTime(), event.getAction(), pointerType, event.getButtonState(), event.getX(), event.getY(), event.getPressure()); } else { @@ -507,7 +508,22 @@ public class QtNative static public void sendTrackballEvent(MotionEvent event, int id) { - switch (event.getAction()) { + sendMouseEvent(event,id); + } + + static public boolean sendGenericMotionEvent(MotionEvent event, int id) + { + if (((event.getAction() & (MotionEvent.ACTION_SCROLL | MotionEvent.ACTION_HOVER_MOVE)) == 0) + || (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != InputDevice.SOURCE_CLASS_POINTER) { + return false; + } + + return sendMouseEvent(event, id); + } + + static public boolean sendMouseEvent(MotionEvent event, int id) + { + switch (event.getActionMasked()) { case MotionEvent.ACTION_UP: mouseUp(id, (int) event.getX(), (int) event.getY()); break; @@ -517,28 +533,27 @@ public class QtNative m_oldx = (int) event.getX(); m_oldy = (int) event.getY(); break; - + case MotionEvent.ACTION_HOVER_MOVE: case MotionEvent.ACTION_MOVE: - int dx = (int) (event.getX() - m_oldx); - int dy = (int) (event.getY() - m_oldy); - if (Math.abs(dx) > 5 || Math.abs(dy) > 5) { + if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) { + mouseMove(id, (int) event.getX(), (int) event.getY()); + } else { + int dx = (int) (event.getX() - m_oldx); + int dy = (int) (event.getY() - m_oldy); + if (Math.abs(dx) > 5 || Math.abs(dy) > 5) { mouseMove(id, (int) event.getX(), (int) event.getY()); m_oldx = (int) event.getX(); m_oldy = (int) event.getY(); + } } break; + case MotionEvent.ACTION_SCROLL: + mouseWheel(id, (int) event.getX(), (int) event.getY(), + event.getAxisValue(MotionEvent.AXIS_HSCROLL), event.getAxisValue(MotionEvent.AXIS_VSCROLL)); + break; + default: + return false; } - } - - static public boolean sendGenericMotionEvent(MotionEvent event, int id) - { - if (event.getActionMasked() != MotionEvent.ACTION_SCROLL - || (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != InputDevice.SOURCE_CLASS_POINTER) { - return false; - } - - mouseWheel(id, (int) event.getX(), (int) event.getY(), - event.getAxisValue(MotionEvent.AXIS_HSCROLL), event.getAxisValue(MotionEvent.AXIS_VSCROLL)); return true; } @@ -585,6 +600,9 @@ public class QtNative } private static void updateHandles(final int mode, + final int editX, + final int editY, + final int editButtons, final int x1, final int y1, final int x2, @@ -594,7 +612,7 @@ public class QtNative runAction(new Runnable() { @Override public void run() { - m_activityDelegate.updateHandles(mode, x1, y1, x2, y2, rtl); + m_activityDelegate.updateHandles(mode, editX, editY, editButtons, x1, y1, x2, y2, rtl); } }); } |