use of com.codename1.db.Cursor in project CodenameOne by codenameone.
the class SQLMap method createTable.
/**
* Creates a table matching the given property component if one doesn't exist yet
* @param cmp the business object
* @return true if the table was created false if it already existed
*/
public boolean createTable(PropertyBusinessObject cmp) throws IOException {
String tableName = getTableName(cmp);
Cursor cr = null;
boolean has = false;
try {
cr = executeQuery("SELECT * FROM sqlite_master WHERE type='table' AND name='" + tableName + "'");
has = cr.next();
} finally {
if (cr != null) {
cr.close();
}
}
if (has) {
return false;
}
StringBuilder createStatement = new StringBuilder("CREATE TABLE ");
createStatement.append(tableName);
createStatement.append(" (");
String pkName = (String) cmp.getPropertyIndex().getMetaDataOfClass("cn1$pk");
boolean autoIncrement = cmp.getPropertyIndex().getMetaDataOfClass("cn1$autoinc") != null;
boolean first = true;
for (PropertyBase p : cmp.getPropertyIndex()) {
SqlType tp = getSqlType(p);
if (tp == SqlType.SQL_EXCLUDE) {
continue;
}
if (!first) {
createStatement.append(",");
}
first = false;
String columnName = getColumnName(p);
createStatement.append(columnName);
createStatement.append(" ");
createStatement.append(tp.dbType);
if (columnName.equalsIgnoreCase(pkName)) {
createStatement.append(" PRIMARY KEY");
if (autoIncrement) {
createStatement.append(" AUTOINCREMENT");
}
}
}
createStatement.append(")");
execute(createStatement.toString());
return true;
}
use of com.codename1.db.Cursor in project CodenameOne by codenameone.
the class ResetableTextWatcher method edit.
/**
* Entry point for using this class
* @param impl The current running activity
* @param component Any subclass of com.codename1.ui.TextArea
* @param inputType One of the TextArea's input-type constants
*/
public static void edit(final AndroidImplementation impl, final Component component, final int inputType) {
if (impl.getActivity() == null) {
throw new IllegalArgumentException("activity is null");
}
if (component == null) {
throw new IllegalArgumentException("component is null");
}
if (!(component instanceof TextArea)) {
throw new IllegalArgumentException("component must be instance of TextArea");
}
final TextArea textArea = (TextArea) component;
final String initialText = textArea.getText();
textArea.putClientProperty("InPlaceEditView.initialText", initialText);
// The very first time we try to edit a string, let's determine if the
// system default is to do async editing. If the system default
// is not yet set, we set it here, and it will be used as the default from now on
// We do this because the nativeInstance.isAsyncEditMode() value changes
// to reflect the currently edited field so it isn't a good way to keep a
// system default.
String defaultAsyncEditingSetting = Display.getInstance().getProperty("android.VKBAlwaysOpen", null);
if (defaultAsyncEditingSetting == null) {
defaultAsyncEditingSetting = impl.isAsyncEditMode() ? "true" : "false";
Display.getInstance().setProperty("android.VKBAlwaysOpen", defaultAsyncEditingSetting);
}
boolean asyncEdit = "true".equals(defaultAsyncEditingSetting) ? true : false;
// Check if the form has any setting for asyncEditing that should override
// the application defaults.
final Form parentForm = component.getComponentForm();
if (parentForm == null) {
com.codename1.io.Log.p("Attempt to edit text area that is not on a form. This is not supported");
return;
}
if (parentForm.getClientProperty("asyncEditing") != null) {
Object async = parentForm.getClientProperty("asyncEditing");
if (async instanceof Boolean) {
asyncEdit = ((Boolean) async).booleanValue();
// Log.p("Form overriding asyncEdit due to asyncEditing client property: "+asyncEdit);
}
}
if (parentForm.getClientProperty("android.asyncEditing") != null) {
Object async = parentForm.getClientProperty("android.asyncEditing");
if (async instanceof Boolean) {
asyncEdit = ((Boolean) async).booleanValue();
// Log.p("Form overriding asyncEdit due to ios.asyncEditing client property: "+asyncEdit);
}
}
if (parentForm.isFormBottomPaddingEditingMode()) {
asyncEdit = true;
}
// then this will override all other settings.
if (component.getClientProperty("asyncEditing") != null) {
Object async = component.getClientProperty("asyncEditing");
if (async instanceof Boolean) {
asyncEdit = ((Boolean) async).booleanValue();
// Log.p("Overriding asyncEdit due to field asyncEditing client property: "+asyncEdit);
}
}
if (component.getClientProperty("android.asyncEditing") != null) {
Object async = component.getClientProperty("android.asyncEditing");
if (async instanceof Boolean) {
asyncEdit = ((Boolean) async).booleanValue();
// Log.p("Overriding asyncEdit due to field ios.asyncEditing client property: "+asyncEdit);
}
}
// if true, then in async mode we are currently editing and are switching to another field
final boolean isEditedFieldSwitch;
// If we are already editing, we need to finish that up before we proceed to edit the next field.
synchronized (editingLock) {
if (mIsEditing) {
if (impl.isAsyncEditMode()) {
// Using isEditedFieldSwitch was causing issues with cursors not showing up.
// https://github.com/codenameone/CodenameOne/issues/2353
// https://stackoverflow.com/questions/49004370/focus-behaviour-in-textarea-in-cn1
// Disabling this feature by default now, but can be re-enabled by setting
// Display.getInstance().setProperty("android.reuseTextEditorOnSwitch", "true");
// This editedFieldSwitch feature was added a while back to improve experience on older
// Android devices where the field switching was going too slow.
// https://github.com/codenameone/CodenameOne/issues/2012
// This issue was resolved in this commit (https://github.com/jaanushansen/CodenameOne/commit/f3e53a80704149e4d7cde276d01c1368bcdcfe2c)
// which was submitted as part of a pull request. This fix has been the source of several
// regressions, mostly related to properties not being propagated properly when a text field is changed
// However, this issue (with the cursor not showing up), doesn't appear to have a simple solution
// so, I'm disabling this feature for now.
isEditedFieldSwitch = "true".equals(Display.getInstance().getProperty("android.reuseTextEditorOnSwitch", "false"));
final String[] out = new String[1];
TextArea prevTextArea = null;
if (sInstance != null && sInstance.mLastEditText != null) {
prevTextArea = sInstance.mLastEditText.getTextArea();
}
if (prevTextArea != null) {
final TextArea fPrevTextArea = prevTextArea;
final String retVal = sInstance.mLastEditText.getText().toString();
Display.getInstance().callSerially(new Runnable() {
public void run() {
Display.getInstance().onEditingComplete(fPrevTextArea, retVal);
}
});
}
InPlaceEditView.setEditedTextField(textArea);
nextTextArea = null;
} else {
isEditedFieldSwitch = false;
final InPlaceEditView instance = sInstance;
if (instance != null && instance.mEditText != null && instance.mEditText.mTextArea == textArea) {
instance.showTextEditorAgain();
return;
}
if (!isClosing && sInstance != null && sInstance.mEditText != null) {
isClosing = true;
impl.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
instance.endEditing(REASON_UNDEFINED, true, 0);
}
});
}
afterClose = new Runnable() {
@Override
public void run() {
impl.callHideTextEditor();
Display.getInstance().editString(component, textArea.getMaxSize(), inputType, textArea.getText());
}
};
return;
}
} else {
isEditedFieldSwitch = false;
}
mIsEditing = true;
isClosing = false;
afterClose = null;
}
impl.setAsyncEditMode(asyncEdit);
// textArea.setPreferredSize(prefSize);
if (!impl.isAsyncEditMode() && textArea instanceof TextField) {
((TextField) textArea).setEditable(false);
}
final boolean scrollableParent = isScrollableParent(textArea);
// We wrap the text area so that we can safely pass data across to the
// android UI thread.
final TextAreaData textAreaData = new TextAreaData(textArea);
impl.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
if (!isEditedFieldSwitch) {
releaseEdit();
if (sInstance == null) {
sInstance = new InPlaceEditView(impl);
impl.relativeLayout.addView(sInstance);
}
// Let's try something new here
// We'll ALWAYS try resize edit mode (since it just works better)
// But we'll detect whether the field is still covered by the keyboard
// and switch to pan mode if necessary.
}
if (scrollableParent || parentForm.isFormBottomPaddingEditingMode()) {
setEditMode(true);
} else {
trySetEditMode(true);
}
sInstance.startEditing(impl.getActivity(), textAreaData, initialText, inputType, isEditedFieldSwitch);
}
});
final String[] out = new String[1];
// In order to reuse the code the runs after edit completion, we will wrap it in a runnable
// For sync edit mode, we will just run onComplete.run() at the end of this method. For
// Async mode we add the Runnable to the textarea as a client property, then run it
// when editing eventually completes.
Runnable onComplete = new Runnable() {
public void run() {
if (!impl.isAsyncEditMode() && textArea instanceof TextField) {
((TextField) textArea).setEditable(true);
}
textArea.setPreferredSize(null);
if (sInstance != null && sInstance.mLastEditText != null && sInstance.mLastEditText.mTextArea == textArea) {
String retVal = sInstance.mLastEditText.getText().toString();
if (!impl.isAsyncEditMode()) {
sInstance.mLastEditText = null;
impl.getActivity().runOnUiThread(new Runnable() {
public void run() {
releaseEdit();
}
});
}
out[0] = retVal;
} else {
out[0] = initialText;
}
Display.getInstance().onEditingComplete(component, out[0]);
if (impl.isAsyncEditMode()) {
impl.callHideTextEditor();
} else {
// lock.
if (sInstance != null) {
Display.getInstance().invokeAndBlock(new Runnable() {
public void run() {
while (sInstance != null) {
com.codename1.io.Util.sleep(5);
}
}
});
}
}
// Release the editing flag
synchronized (editingLock) {
mIsEditing = false;
}
// as a runnable ... this should take priority over the "nextTextArea" setting
if (afterClose != null) {
Display.getInstance().callSerially(afterClose);
} else if (nextTextArea != null) {
final TextArea next = nextTextArea;
nextTextArea = null;
next.requestFocus();
Display.getInstance().callSerially(new Runnable() {
public void run() {
Display.getInstance().editString(next, next.getMaxSize(), next.getConstraint(), next.getText());
}
});
}
}
};
textArea.requestFocus();
textArea.repaint();
if (impl.isAsyncEditMode()) {
component.putClientProperty("android.onAsyncEditingComplete", onComplete);
return;
}
// Make this call synchronous
// We set this flag so that waitForEditCompletion can block on it.
// The flag will be released inside the endEditing method which will
// allow the method to proceed.
waitingForSynchronousEditingCompletion = true;
waitForEditCompletion();
onComplete.run();
}
use of com.codename1.db.Cursor in project CodenameOne by codenameone.
the class ResetableTextWatcher method hideTextEditor.
/**
* Hides the native text editor while keeping the active async edit session going.
* This will effectively hide the native text editor, and show the light-weight text area
* with cursor still in the correct position.
*/
private void hideTextEditor() {
if (!mIsEditing || textEditorHidden || mEditText == null) {
return;
}
textEditorHidden = true;
final TextArea ta = mEditText.mTextArea;
// Since this may be called off the UI thread, we need to issue async request on UI thread
// to hide the text area.
impl.getActivity().runOnUiThread(new Runnable() {
public void run() {
if (mEditText != null && mEditText.mTextArea == ta) {
// Note: Setting visibility to GONE doesn't work here because the TextWatcher
// will stop receiving input from the keyboard, so we don't have a way to
// reactivate the text editor when the user starts typing again. Using the margin
// to move it off screen keeps the text editor active.
mEditLayoutParams.setMargins(-Display.getInstance().getDisplayWidth(), 0, 0, 0);
InPlaceEditView.this.requestLayout();
final int cursorPos = mEditText.getSelectionStart();
// Since we are going to be displaying the CN1 text area now, we need to update
// the cursor. That needs to happen on the EDT.
Display.getInstance().callSerially(new Runnable() {
public void run() {
if (mEditText != null && mEditText.mTextArea == ta && mIsEditing && textEditorHidden) {
if (ta instanceof TextField) {
((TextField) ta).setCursorPosition(cursorPos);
}
}
}
});
}
}
});
// Repaint the CN1 text area on the EDT. This is necessary because while the native editor
// was shown, the cn1 text area paints only its background. Now that the editor is hidden
// it should paint its foreground also.
Display.getInstance().callSerially(new Runnable() {
public void run() {
if (mEditText != null && mEditText.mTextArea != null) {
mEditText.mTextArea.repaint();
}
}
});
// repaintTextEditor(true);
}
use of com.codename1.db.Cursor in project CodenameOne by codenameone.
the class DefaultLookAndFeel method getTextFieldCursorX.
/**
* Calculates the position of the text field cursor within the string
*/
private int getTextFieldCursorX(TextArea ta) {
Style style = ta.getStyle();
Font f = style.getFont();
// display ******** if it is a password field
String displayText = getTextFieldString(ta);
String inputMode = ta.getInputMode();
int inputModeWidth = f.stringWidth(inputMode);
// QWERTY devices don't quite have an input mode hide it also when we have a VK
if (ta.isQwertyInput() || Display.getInstance().isVirtualKeyboardShowing()) {
inputMode = "";
inputModeWidth = 0;
}
int xPos = 0;
int cursorCharPosition = ta.getCursorX();
int cursorX = 0;
int x = 0;
if (reverseAlignForBidi(ta) == Component.RIGHT) {
if (Display.getInstance().isBidiAlgorithm()) {
// char[] dest = displayText.toCharArray();
cursorCharPosition = Display.getInstance().getCharLocation(displayText, cursorCharPosition - 1);
if (cursorCharPosition == -1) {
xPos = f.stringWidth(displayText);
} else {
displayText = Display.getInstance().convertBidiLogicalToVisual(displayText);
if (!isRTLOrWhitespace((displayText.charAt(cursorCharPosition)))) {
cursorCharPosition++;
}
xPos = f.stringWidth(displayText.substring(0, cursorCharPosition));
}
}
int displayX = ta.getX() + ta.getWidth() - style.getPaddingLeft(ta.isRTL()) - f.stringWidth(displayText);
cursorX = displayX + xPos;
x = 0;
} else {
if (cursorCharPosition > 0) {
cursorCharPosition = Math.min(displayText.length(), cursorCharPosition);
xPos = f.stringWidth(displayText.substring(0, cursorCharPosition));
}
cursorX = ta.getX() + style.getPaddingLeft(ta.isRTL()) + xPos;
if (ta.isSingleLineTextArea() && ta.getWidth() > (f.getHeight() * 2) && cursorX >= ta.getWidth() - inputModeWidth - style.getPaddingLeft(ta.isRTL())) {
if (x + xPos >= ta.getWidth() - inputModeWidth - style.getPaddingLeftNoRTL() - style.getPaddingRightNoRTL()) {
x = ta.getWidth() - inputModeWidth - style.getPaddingLeftNoRTL() - style.getPaddingRightNoRTL() - xPos - 1;
}
}
}
return cursorX + x;
}
use of com.codename1.db.Cursor in project CodenameOne by codenameone.
the class AndroidImplementation method onActivityResult.
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == ZOOZ_PAYMENT) {
((IntentResultListener) pur).onActivityResult(requestCode, resultCode, intent);
return;
}
if (resultCode == Activity.RESULT_OK) {
if (requestCode == CAPTURE_IMAGE) {
try {
String imageUri = (String) Storage.getInstance().readObject("imageUri");
Vector pathandId = StringUtil.tokenizeString(imageUri, ";");
String path = (String) pathandId.get(0);
String lastId = (String) pathandId.get(1);
Storage.getInstance().deleteStorageFile("imageUri");
clearMediaDB(lastId, path);
callback.fireActionEvent(new ActionEvent(path));
return;
} catch (Exception e) {
e.printStackTrace();
}
} else if (requestCode == CAPTURE_VIDEO) {
String path = (String) Storage.getInstance().readObject("videoUri");
Storage.getInstance().deleteStorageFile("videoUri");
callback.fireActionEvent(new ActionEvent(path));
return;
} else if (requestCode == CAPTURE_AUDIO) {
Uri data = intent.getData();
String path = convertImageUriToFilePath(data, getContext());
callback.fireActionEvent(new ActionEvent(path));
return;
} else if (requestCode == OPEN_GALLERY) {
Uri selectedImage = intent.getData();
String scheme = intent.getScheme();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContext().getContentResolver().query(selectedImage, filePathColumn, null, null, null);
// this happens on Android devices, not exactly sure what the use case is
if (cursor == null) {
callback.fireActionEvent(null);
return;
}
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePath = cursor.getString(columnIndex);
cursor.close();
if (filePath == null && "content".equals(scheme)) {
// locally
try {
InputStream inputStream = getContext().getContentResolver().openInputStream(selectedImage);
if (inputStream != null) {
String name = getContentName(getContext().getContentResolver(), selectedImage);
if (name != null) {
filePath = getAppHomePath() + getFileSystemSeparator() + name;
File f = new File(filePath);
OutputStream tmp = createFileOuputStream(f);
byte[] buffer = new byte[1024];
int read = -1;
while ((read = inputStream.read(buffer)) > -1) {
tmp.write(buffer, 0, read);
}
tmp.close();
inputStream.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
callback.fireActionEvent(new ActionEvent(filePath));
return;
} else {
if (callback != null) {
callback.fireActionEvent(new ActionEvent("ok"));
}
return;
}
}
// clean imageUri
String imageUri = (String) Storage.getInstance().readObject("imageUri");
if (imageUri != null) {
Storage.getInstance().deleteStorageFile("imageUri");
}
if (callback != null) {
callback.fireActionEvent(null);
}
}
Aggregations