📄 appuifwmodule.cpp
字号:
virtual ~CListBoxCallback() {
Py_XDECREF(iCallback);
delete iAsyncCallback;
}
virtual void HandleListBoxEventL(CEikListBox* /* aListBox */, TListBoxEvent aEventType) {
if (iCallback && (aEventType == EEventEnterKeyPressed ||
aEventType == EEventItemDoubleClicked)) {
PyEval_RestoreThread(PYTHON_TLS->thread_state);
/*Increment of reference count of iListbox. It is used not to delete iListBox
prematurely. Possibly, iCallback is such a
function (i.e. function from Python script that would change app.body from
current listbox to something else) that would
cause deletion of iListBox object.
Asynchronous callback is later used to call decrefObject() which would
decrease the reference to iListBox once when HandleListBoxEventL() returns, and
UI processing is done. This fixes bug 1481966*/
Py_INCREF(iListBox);
app_callback_handler(iCallback);
if (iListBox->ob_refcnt == 1){
TCallBack cb(&decrefObject, iListBox);
iAsyncCallback = new (ELeave) CAsyncCallBack(cb, CActive::EPriorityHigh);
iAsyncCallback->CallBack();
}
else {
Py_DECREF(iListBox);
}
PyEval_SaveThread();
}
}
private:
PyObject *iCallback;
PyObject *iListBox;
CAsyncCallBack *iAsyncCallback;
};
struct Listbox_object {
PyObject_VAR_HEAD
CEikListBox *ob_control;
CAppuifwEventBindingArray* ob_event_bindings;
ListboxType ob_lb_type;
CListBoxCallback *ob_listbox_callback;
CArrayPtrFlat<CGulIcon>* ob_icons;
};
/* An internal helper function */
PyObject *RemoveTabs(PyObject *unicodeString )
{
_LIT(KEmpty, " ");
TBuf<(KMaxFileName)> temp;
temp.Append(PyUnicode_AsUnicode(unicodeString),
Min(PyUnicode_GetSize(unicodeString), KMaxFileName));
TInt res = KErrNotFound;
res = temp.Find(KSeparatorTab);
while (res!=KErrNotFound)
{
res = temp.Find(KSeparatorTab);
if ((res != KErrNotFound) ) {
temp.Replace(res, 1, KEmpty );
}
}
PyObject *newUnicodeObject = Py_BuildValue("u#", temp.Ptr(), temp.Length());
return newUnicodeObject;
}
/* An internal helper function */
static TInt Listbox_create_itemslist(ListboxType lb_type,
PyObject* list,
CDesCArray*& items_list,
TBool is_popup_style = EFalse,
CArrayPtr<CGulIcon>* icons = NULL)
{
Icon_object *io = NULL;
TBool items_list_borrowed = ETrue;
if (!items_list) {
if (!(items_list = new CDesCArrayFlat(5)))
return KErrNoMemory;
else
items_list_borrowed = EFalse;
}
TInt error = KErrNone;
TBuf<((KMaxFileName+1)*2)> temp;
int sz = PyList_Size(list);
CEikonEnv* env = CEikonEnv::Static();
for (int i = 0; i < sz; i++) {
if (lb_type == ESingleListbox) {
PyObject* s = PyList_GetItem(list, i);
if (!PyUnicode_Check(s))
error = KErrArgument;
else {
if (is_popup_style) {
temp.Copy(KEmptyString);
}
else {
temp.Copy(KSeparatorTab);
}
temp.Append(PyUnicode_AsUnicode(RemoveTabs(s)),
Min(PyUnicode_GetSize(s), KMaxFileName));
}
}
else if (lb_type == EDoubleListbox) {
PyObject* t = PyList_GetItem(list, i);
if (!PyTuple_Check(t))
error = KErrArgument;
else {
PyObject* s1 = PyTuple_GetItem(t, 0);
PyObject* s2 = PyTuple_GetItem(t, 1);
if ((!PyUnicode_Check(s1)) || (!PyUnicode_Check(s2))) {
error = KErrArgument;
}
else {
if (is_popup_style) {
temp.Copy(KEmptyString);
}
else {
temp.Copy(KSeparatorTab);
}
temp.Append(PyUnicode_AsUnicode(RemoveTabs(s1)),
Min(PyUnicode_GetSize(s1), KMaxFileName));
temp.Append(KSeparatorTab);
temp.Append(PyUnicode_AsUnicode(RemoveTabs(s2)),
Min(PyUnicode_GetSize(s2), KMaxFileName));
}
}
}
else if (lb_type == ESingleGraphicListbox) {
PyObject* t = PyList_GetItem(list, i);
if (!PyTuple_Check(t)) {
error = KErrArgument;
}
else {
PyObject* s1; // = PyTuple_GetItem(t, 0);
if (!PyArg_ParseTuple(t, "OO!", &s1, &Icon_type, &io)) {
error = KErrArgument;
}
else {
if (is_popup_style) {
temp.Copy(KEmptyString);
}
else {
temp.Copy(KEmptyString);
temp.AppendNum(i);
temp.Append(KSeparatorTab);
}
temp.Append(PyUnicode_AsUnicode(RemoveTabs(s1)), Min(PyUnicode_GetSize(s1), KMaxFileName));
}
// error in argument:
if (error != KErrNone) {
SPyErr_SetFromSymbianOSErr(error);
delete items_list;
items_list = NULL;
return error;
}
CGulIcon* iIcon = NULL;
#if SERIES60_VERSION>=28
CFbsBitmap* bitMap = NULL;
CFbsBitmap* mask = NULL;
TRAP(error, {
AknIconUtils::CreateIconL(bitMap, mask, io->icon->ob_file, io->icon->ob_bmpId, io->icon->ob_maskId);
iIcon = CGulIcon::NewL(bitMap, mask);
});
#else
TRAP(error,
iIcon = env->CreateIconL(io->icon->ob_file, io->icon->ob_bmpId, io->icon->ob_maskId) );
#endif /* SERIES60_VERSION */
if (error != KErrNone) {
SPyErr_SetFromSymbianOSErr(error);
delete items_list;
items_list = NULL;
return error;
}
TRAP(error, icons->AppendL(iIcon) );
if (error != KErrNone) {
SPyErr_SetFromSymbianOSErr(error);
delete items_list;
items_list = NULL;
return error;
}
}
}
else if (lb_type == EDoubleGraphicListbox) {
PyObject* t = PyList_GetItem(list, i);
if (!PyTuple_Check(t)) {
error = KErrArgument;
}
else {
PyObject* s1; // = PyTuple_GetItem(t, 0);
PyObject* s2; // = PyTuple_GetItem(t, 1);
if (!PyArg_ParseTuple(t, "OOO!", &s1, &s2, &Icon_type, &io)) {
error = KErrArgument;
}
else {
if (is_popup_style) {
temp.Copy(KEmptyString);
}
else {
temp.Copy(KEmptyString);
temp.AppendNum(i);
temp.Append(KSeparatorTab);
}
temp.Append(PyUnicode_AsUnicode(RemoveTabs(s1)), Min(PyUnicode_GetSize(s1), KMaxFileName));
temp.Append(KSeparatorTab);
temp.Append(PyUnicode_AsUnicode(RemoveTabs(s2)), Min(PyUnicode_GetSize(s2), KMaxFileName));
}
// error in argument:
if (error != KErrNone) {
SPyErr_SetFromSymbianOSErr(error);
delete items_list;
items_list = NULL;
return error;
}
CGulIcon* iIcon = NULL;
#if SERIES60_VERSION>=28
CFbsBitmap* bitMap = NULL;
CFbsBitmap* mask = NULL;
TRAP(error, { AknIconUtils::CreateIconL(
bitMap, mask, io->icon->ob_file, io->icon->ob_bmpId, io->icon->ob_maskId);
iIcon = CGulIcon::NewL(bitMap, mask);
});
#else
TRAP(error,
iIcon = env->CreateIconL(io->icon->ob_file, io->icon->ob_bmpId, io->icon->ob_maskId) );
#endif /* SERIES60_VERSION */
if (error != KErrNone) {
SPyErr_SetFromSymbianOSErr(error);
delete items_list;
items_list = NULL;
return error;
}
TRAP(error, icons->AppendL(iIcon) );
if (error != KErrNone) {
SPyErr_SetFromSymbianOSErr(error);
delete items_list;
items_list = NULL;
return error;
}
}
}
if (error == KErrNone) {
TRAP(error, items_list->AppendL(temp));
}
if ((error != KErrNone) && (!items_list_borrowed)) {
delete items_list;
items_list = NULL;
break;
}
}
return error;
}
extern "C" PyObject *
new_Listbox_object(PyObject* /*self*/, PyObject *args)
{
TInt error = KErrNone;
PyObject* list;
PyObject* cb = NULL;
if (!PyArg_ParseTuple(args, "O!|O", &PyList_Type, &list, &cb))
return NULL;
if (cb && !PyCallable_Check(cb)) {
PyErr_SetString(PyExc_TypeError, "callable expected");
return NULL;
}
if (PyList_Size(list) <= 0) {
PyErr_SetString(PyExc_ValueError, "non-empty list expected");
return NULL;
}
Listbox_object *op = PyObject_New(Listbox_object, &Listbox_type);
if (op == NULL)
return PyErr_NoMemory();
op->ob_listbox_callback = NULL;
op->ob_event_bindings = NULL;
op->ob_control = NULL;
if (!(op->ob_event_bindings = new CAppuifwEventBindingArray())) {
PyObject_Del(op);
return PyErr_NoMemory();
}
if (PyTuple_Check(PyList_GetItem(list, 0))) {
switch (PyTuple_Size(PyList_GetItem(list, 0))) {
case 2: {
PyObject* secondObj = PyTuple_GetItem(PyList_GetItem(list, 0), 1);
if (PyUnicode_Check(secondObj) )
op->ob_lb_type = EDoubleListbox;
else
op->ob_lb_type = ESingleGraphicListbox;
break;
}
case 3:
op->ob_lb_type = EDoubleGraphicListbox;
break;
default:
PyErr_SetString(PyExc_ValueError, "tuple must include 2 or 3 elements");
return NULL;
}
}
else {
op->ob_lb_type = ESingleListbox;
}
if (error == KErrNone) {
switch(op->ob_lb_type) {
case ESingleListbox:
op->ob_control = new CAknSingleStyleListBox();
break;
case EDoubleListbox:
op->ob_control = new CAknDoubleStyleListBox();
break;
case ESingleGraphicListbox:
op->ob_control = new CAknSingleGraphicStyleListBox();
break;
case EDoubleGraphicListbox:
op->ob_control = new CAknDoubleLargeStyleListBox();
break;
}
if (op->ob_control == NULL) {
PyObject_Del(op);
return PyErr_NoMemory();
}
op->ob_icons = NULL;
}
CAmarettoAppUi* pyappui = MY_APPUI;
CCoeControl* cont = pyappui->iContainer;
if (error == KErrNone) {
TRAP(error, {
op->ob_control->SetContainerWindowL(*cont);
if (op->ob_lb_type == ESingleListbox)
((CAknSingleStyleListBox*)op->ob_control)->
ConstructL(cont, EAknListBoxSelectionList);
else
if (op->ob_lb_type == EDoubleListbox)
((CAknDoubleStyleListBox*)op->ob_control)->
ConstructL(cont, EAknListBoxSelectionList);
else
if (op->ob_lb_type == ESingleGraphicListbox)
((CAknSingleGraphicStyleListBox*)op->ob_control)->
ConstructL(cont, EAknListBoxSelectionList);
else
if (op->ob_lb_type == EDoubleGraphicListbox)
((CAknDoubleLargeStyleListBox*)op->ob_control)->
ConstructL(cont, EAknListBoxSelectionList);
});
}
CDesCArray *items_list = NULL;
if ( (op->ob_lb_type==ESingleGraphicListbox) || (op->ob_lb_type==EDoubleGraphicListbox) )
TRAP(error,
op->ob_icons = new(ELeave) CArrayPtrFlat<CGulIcon>(5));
if (error == KErrNone)
error = Listbox_create_itemslist(op->ob_lb_type, list, items_list, NULL, op->ob_icons);
if (error == KErrNone) {
if (op->ob_lb_type == ESingleListbox)
((CAknSingleStyleListBox*)op->ob_control)->
Model()->SetItemTextArray(items_list); /* ownership transfer */
else
if (op->ob_lb_type == EDoubleListbox)
((CAknDoubleStyleListBox*)op->ob_control)->
Model()->SetItemTextArray(items_list);
else
if (op->ob_lb_type == ESingleGraphicListbox) {
if (op->ob_icons != NULL)
((CAknColumnListBox*)op->ob_control)->ItemDrawer()->ColumnData()->SetIconArray(op->ob_icons);
((CAknSingleGraphicStyleListBox*)op->ob_control)->Model()->SetItemTextArray(items_list);
}
else
if (op->ob_lb_type == EDoubleGraphicListbox) {
if (op->ob_icons != NULL)
((CEikFormattedCellListBox*)op->ob_control)->ItemDrawer()->
ColumnData()->SetIconArray(op->ob_icons);
((CAknDoubleLargeStyleListBox*)op->ob_control)->Model()->SetItemTextArray(items_list);
}
TRAP(error, op->ob_listbox_callback = new (ELeave) CListBoxCallback(cb, (PyObject *)op));
if (error != KErrNone) {
if (op->ob_listbox_callback != NULL)
delete op->ob_listbox_callback;
if (op->ob_event_bindings != NULL)
delete op->ob_event_bindings;
if (op->ob_control != NULL)
delete op->ob_control;
PyObject_Del(op);
op = NULL;
return SPyErr_SetFromSymbianOSErr(error);
}
else {
((CEikListBox*)op->ob_control)->SetListBoxObserver(op->ob_listbox_callback);
return (PyObject *) op;
}
} else {
Py_DECREF(op);
return SPyErr_SetFromSymbianOSErr(error);
}
}
extern "C" PyObject*
Listbox_index(Listbox_object *self)
{
return Py_BuildValue("i", self->ob_control->CurrentItemIndex());
}
extern "C" PyObject*
Listbox_set_list(Listbox_object *self, PyObject *args)
{
TInt error = KErrNone;
int current = 0;
PyObject* list;
if (!PyArg_ParseTuple(args, "O!|i", &PyList_Type, &list, ¤t))
return NULL;
if (PyList_Size(list) <= 0) {
PyErr_SetString(PyExc_ValueError, "non-empty list expected");
return NULL;
}
if (PyTuple_Check(PyList_GetItem(list, 0))) {
if ( (self->ob_lb_type != EDoubleListbox) && (self->ob_lb_type != ESingleGraphicListbox) && (self->ob_lb_type != EDoubleGraphicListbox) ) {
PyErr_SetString(PyExc_ValueError, "Listbox type mismatch");
return NULL;
}
}
else {
if (self->ob_lb_type != ESingleListbox) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -