📄 capplication.cpp
字号:
/*************************************************************************** CApplication.cpp The KDE DCOP Application class (c) 2000-2003 Beno顃 Minisini <gambas@users.sourceforge.net> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.***************************************************************************/#define __CAPPLICATION_CPP#include <qstringlist.h>#include <qpixmap.h>#include <qvariant.h>#include <dcopclient.h>#include <kapplication.h>#include <kdatastream.h>#include <kurl.h>#include <kprocess.h>#include "gambas.h"#include "main.h"#include "../CPicture.h"#include "../CImage.h"#include "../CMouse.h"#include "../CFont.h"#include "CApplication.h"//#define DEBUG_MEtypedef struct { char *dcop; GB_TYPE type; } TYPE_CONV;enum { QT_T_VOID, QT_T_ASYNC, QT_T_BOOL, QT_T_INT, QT_T_UNSIGNED, QT_T_UINT, QT_T_LONG, QT_T_ULONG, QT_T_QCOLOR, QT_T_FLOAT, QT_T_DOUBLE, QT_T_QCSTRING, QT_T_QSTRING, QT_T_KURL, QT_T_KURL_LIST, QT_T_QVARIANT, QT_T_QCSTRINGLIST, QT_T_QSTRINGLIST, QT_T_DCOPREF, QT_T_QVALUELIST_DCOPREF, QT_T_QPIXMAP, QT_T_QIMAGE, QT_T_QCURSOR, QT_T_QPOINT, QT_T_QSIZE, QT_T_QRECT, QT_T_QFONT};static TYPE_CONV type_conv[] ={ { "void", GB_T_VOID }, { "ASYNC", GB_T_VOID }, { "bool", GB_T_BOOLEAN }, { "int", GB_T_INTEGER }, { "unsigned", GB_T_INTEGER }, { "uint", GB_T_INTEGER }, { "long", GB_T_INTEGER }, { "ulong", GB_T_INTEGER }, { "QColor", GB_T_INTEGER }, { "float", GB_T_FLOAT }, { "double", GB_T_FLOAT }, { "QCString", GB_T_STRING }, { "QString", GB_T_STRING }, { "KURL", GB_T_STRING }, { "KURL::List", (GB_TYPE)"String[]" }, { "QVariant", GB_T_VARIANT }, { "QCStringList", (GB_TYPE)"String[]" }, { "QStringList", (GB_TYPE)"String[]" }, { "DCOPRef", (GB_TYPE)"DCOPRef" }, { "QValueList<DcopRef>", (GB_TYPE)"Object[]" }, { "QPixmap", (GB_TYPE)"Picture" }, { "QImage", (GB_TYPE)"Image" }, { "QCursor", (GB_TYPE)"Cursor" }, { "QPoint", (GB_TYPE)"Integer[]" }, { "QSize", (GB_TYPE)"Integer[]" }, { "QRect", (GB_TYPE)"Integer[]" }, { "QFont", (GB_TYPE)"Font" }, { NULL }};static QAsciiDict< CAPPLICATION > appCache;static int get_type(const char *type){ TYPE_CONV *p; int i; if (type == 0 || *type == 0) return 0; for (p = type_conv, i = 0; p->dcop; p++, i++) if (GB.strcasecmp(p->dcop, type) == 0) return i; return (-1);}static void flush_application(){ QAsciiDictIterator<CAPPLICATION> it(appCache); CAPPLICATION *app; //qDebug("flush_application"); while (it.current()) { //delete it.current()->pixmap; app = it.current(); GB.Unref((void **)&app); ++it; }}static CAPPLICATION *get_application(const char *name, bool exec = true){ QCString app; CAPPLICATION *_object = 0; bool reg; DCOPClient *dcop = kapp->dcopClient(); app = name; reg = dcop->isApplicationRegistered(app); if (!reg) { QCStringList apps = dcop->registeredApplications(); QCString appId = dcop->appId(); for (QCStringList::ConstIterator it = apps.begin(); it != apps.end(); ++it) { if ((*it) != appId && (*it).left(9) != "anonymous") { if ((*it).find(app) == 0) { app = *it; reg = true; break; } } } } #ifdef DEBUG_ME if (reg) qDebug("Application is already registered"); #endif if (!reg) { QString sName(name); QString url; QString error; int i; i = sName.find(' '); if (i >= 0) { url = sName.mid(i + 1).stripWhiteSpace(); sName = sName.left(i).stripWhiteSpace(); } if (exec) { #ifdef DEBUG_ME qDebug("starting %s...", sName.latin1()); #endif kapp->startServiceByDesktopName(sName, url, &error); } if (error.length()) { GB.Error("Cannot start KDE application: &1", error.latin1()); return NULL; } else return get_application(name, false); } if (!appCache.isEmpty()) _object = appCache[app]; if (!_object) { GB.New((void **)&_object, GB.FindClass("KDEApplication"), NULL, NULL); GB.Ref(THIS); GB.NewString(&THIS->name, app, app.length()); THIS->object = NULL; THIS->cache = new QAsciiDict< QDict<CFunction> >(17, false); THIS->cache->setAutoDelete(true); appCache.insert(app, THIS); } return THIS;}static CDCOPREF *make_dcopref(DCOPRef& dcopref){ CDCOPREF *_object; if (dcopref.isNull()) return NULL; GB.New((void **)&_object, GB.FindClass("DCOPRef"), NULL, NULL); _object->ref = new DCOPRef(dcopref); //qDebug("Create DCOPREF %p", _object); return _object;}BEGIN_METHOD_VOID(CAPPLICATION_exit) flush_application();END_METHODBEGIN_METHOD_VOID(CAPPLICATION_free) GB.FreeString(&THIS->name); GB.FreeString(&THIS->object); delete THIS->cache; THIS->cache = 0;END_METHODBEGIN_PROPERTY(CAPPLICATION_name) GB.ReturnString(THIS->name);END_PROPERTYBEGIN_METHOD(CAPPLICATION_get, GB_STRING name) GB.ReturnObject(get_application(GB.ToZeroString(ARG(name))));END_METHODstatic void get_object(CAPPLICATION *_object, const char *name){ GB.FreeString(&THIS->object); GB.NewString(&THIS->object, name, 0); GB.ReturnObject(THIS);}BEGIN_METHOD(CAPPLICATION_get_object, GB_STRING object) get_object(THIS, GB.ToZeroString(ARG(object)));END_METHODstatic CFunction *get_function(CAPPLICATION *_object, const char *iname, const char *name, int nparam){ QDict<CFunction> *iface = 0; CFunction *func; if (!iname) iname = "default"; if (!THIS->cache->isEmpty()) iface = (*THIS->cache)[iname]; if (iface == 0) { bool ok; QCStringList funcs; QString dcsign, dctype, dcname; QStringList dcargs; int l, r, i; iface = new QDict<CFunction>(17, false); iface->setAutoDelete(true); #ifdef DEBUG_ME qDebug("**** %s.%s", THIS->name, iname); #endif funcs = kapp->dcopClient()->remoteFunctions(THIS->name, iname, &ok); if (!ok) return NULL; for (QCStringList::ConstIterator it = funcs.begin(); it != funcs.end(); ++it) { //dcsign = kapp->dcopClient()->normalizeFunctionSignature(*it); dcsign = *it; /* Type DCOP de retour */ i = dcsign.find(" "); if (i >= 0) dctype = dcsign.left(i); dcsign = dcsign.mid(i + 1); l = dcsign.find('('); r = dcsign.findRev(')'); if (l < 0 || r < 0) continue; /* Nom DCOP de la m閠hode */ dcname = dcsign.left(l).stripWhiteSpace(); dcsign = dcsign.mid(l + 1, r - l - 1); /* Types des arguments de la m閠hode */ dcargs = QStringList::split(',', dcsign); for (QStringList::Iterator it = dcargs.begin(); it != dcargs.end(); ++it) { (*it) = (*it).stripWhiteSpace(); i = (*it).find(' '); if (i >= 0) (*it) = (*it).left(i); } func = new CFunction(); func->dcopName = dcname + "(" + dcargs.join(",") + ")"; #ifdef DEBUG_ME qDebug("dcopName = %s", (const char *)func->dcopName); #endif /* Nom Gambas de la m閠hode */ dcname += QString::number(dcargs.count()); QString dcname2 = dcname; for(i = 1; i < 256; i++) { dcname2 = dcname; if (i > 1) dcname2 += QString::number(i); if (iface->isEmpty() || iface->find(dcname2) == 0) { func->name = dcname2; break; } } #ifdef DEBUG_ME qDebug("name = %s", (const char *)func->name); #endif func->type = get_type(dctype.latin1()); #ifdef DEBUG_ME qDebug("type = %s", (const char *)dctype); #endif func->args = new int[dcargs.count()]; #ifdef DEBUG_ME for (QStringList::Iterator it = dcargs.begin(); it != dcargs.end(); ++it) qDebug("arg = %s", (*it).latin1()); qDebug(" "); #endif i = 0; for (QStringList::Iterator it = dcargs.begin(); it != dcargs.end(); ++it, ++i) func->args[i] = get_type((*it).latin1()); iface->insert((const char *)func->name, func); } THIS->cache->insert(iname, iface); } if (!iface->isEmpty()) func = (*iface)[QString(name) + QString::number(nparam)]; return func;}#define GET_STRING(_arg) (TO_QSTRING(GB.ToZeroString((GB_STRING *)_arg)))#define GET_OBJECT(_arg, _type) ((_type *)(((GB_OBJECT *)_arg)->value))static bool call_method(CAPPLICATION *_object, const char *object, const char *name, GB_VALUE *args, int nparam, bool error){ int i, n, ret, j; GB_VALUE *arg; bool ok; int type; GB_TYPE gtype; QByteArray data, replyData; CFunction *func; void *ob; n = nparam; func = get_function(THIS, object, name, n); if (!func) { if (error) { if (object) GB.Error("Unknown method: &1.&2.&3", THIS->name, object, name); else GB.Error("Unknown method: &1.&2", THIS->name, name); } return true; } #ifdef DEBUG_ME qDebug("call_method: %s.%s.%s", THIS->name, object, name);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -