dcop
dcopsignals.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <dcopserver.h>
00023 #include <dcopsignals.h>
00024
00025 template class QPtrList<DCOPSignalConnection>;
00026
00027 DCOPSignals::DCOPSignals()
00028 {
00029 connections.setAutoDelete(true);
00030 }
00031
00037 void
00038 DCOPSignals::emitSignal( DCOPConnection *conn, const QCString &_fun, const QByteArray &data, bool excludeSelf)
00039 {
00040 QCString senderObj;
00041 QCString fun = _fun;
00042 int i = fun.find('#');
00043 if (i > -1)
00044 {
00045 senderObj = fun.left(i);
00046 fun = fun.mid(i+1);
00047 }
00048
00049 DCOPSignalConnectionList *list = connections.find(fun);
00050 if (!list) return;
00051 for(DCOPSignalConnection *current = list->first(); current; current = list->next())
00052 {
00053 bool doSend = false;
00054 if (current->senderConn)
00055 {
00056 if (current->senderConn == conn)
00057 doSend = true;
00058 }
00059 else if (!current->sender.isEmpty())
00060 {
00061 if ((conn && current->sender == conn->appId) || (current->sender == "DCOPServer"))
00062 doSend = true;
00063 }
00064 else
00065 {
00066 doSend = true;
00067 }
00068
00069 if (!current->senderObj.isEmpty() &&
00070 (current->senderObj != senderObj))
00071 {
00072 doSend = false;
00073 }
00074
00075 if (excludeSelf && (conn == current->recvConn))
00076 doSend = false;
00077 if (doSend)
00078 {
00079 the_server->sendMessage(current->recvConn, conn ? conn->appId : QCString("DCOPServer"),
00080 current->recvConn->appId, current->recvObj,
00081 current->slot, data);
00082 }
00083 }
00084 }
00085
00096 bool
00097 DCOPSignals::connectSignal( const QCString &sender, const QCString &senderObj,
00098 const QCString &signal,
00099 DCOPConnection *conn, const QCString &receiverObj,
00100 const QCString &slot, bool Volatile)
00101 {
00102
00103 QCString signalArgs, slotArgs;
00104 int i,j;
00105 i = signal.find('(');
00106 if (i < 0) return false;
00107 signalArgs = signal.mid(i+1);
00108 j = signalArgs.find(')');
00109 if (j < 0) return false;
00110 signalArgs.truncate(j);
00111 i = slot.find('(');
00112 if (i < 0) return false;
00113 slotArgs = slot.mid(i+1);
00114 j = slotArgs.find(')');
00115 if (j < 0) return false;
00116 slotArgs.truncate(j);
00117
00118 if(signalArgs != slotArgs)
00119 {
00120
00121 if (signalArgs.length() <= slotArgs.length())
00122 return false;
00123 if ((slotArgs.length() > 0) && (signalArgs[slotArgs.length()] != ','))
00124 return false;
00125 if (signalArgs.left(slotArgs.length()) != slotArgs)
00126 return false;
00127 }
00128
00129 DCOPConnection *senderConn = 0;
00130 if (Volatile)
00131 {
00132 senderConn = the_server->findApp(sender);
00133 if (!senderConn)
00134 return false;
00135 }
00136 DCOPSignalConnection *current = new DCOPSignalConnection;
00137 current->sender = sender;
00138 current->senderObj = senderObj;
00139 current->senderConn = senderConn;
00140 current->signal = signal;
00141 current->recvConn = conn;
00142 current->recvObj = receiverObj;
00143 current->slot = slot;
00144
00145 DCOPSignalConnectionList *list = connections.find(signal);
00146 if (!list)
00147 {
00148 list = new DCOPSignalConnectionList;
00149 connections.insert(signal, list);
00150 }
00151
00152 list->append( current );
00153 conn->signalConnectionList()->append(current);
00154 if (senderConn && senderConn != conn)
00155 senderConn->signalConnectionList()->append(current);
00156 return true;
00157 }
00158
00168 bool
00169 DCOPSignals::disconnectSignal( const QCString &sender, const QCString &senderObj,
00170 const QCString &signal,
00171 DCOPConnection *conn, const QCString &receiverObj,
00172 const QCString &slot)
00173 {
00174 if (sender.isEmpty() && signal.isEmpty())
00175 {
00176 removeConnections(conn, receiverObj);
00177 return true;
00178 }
00179
00180 DCOPSignalConnectionList *list = connections.find(signal);
00181 if (!list)
00182 return false;
00183
00184 DCOPSignalConnection *next = 0;
00185 bool result = false;
00186
00187 for(DCOPSignalConnection *current = list->first(); current; current = next)
00188 {
00189 next = list->next();
00190
00191 if (current->recvConn != conn)
00192 continue;
00193
00194 if (current->senderConn)
00195 {
00196 if (current->senderConn->appId != sender)
00197 continue;
00198 }
00199 else if (current->sender != sender)
00200 continue;
00201
00202 if (!senderObj.isEmpty() &&
00203 (current->senderObj != senderObj))
00204 continue;
00205
00206 if (!receiverObj.isEmpty() &&
00207 (current->recvObj != receiverObj))
00208 continue;
00209
00210 if (!slot.isEmpty() &&
00211 (current->slot != slot))
00212 continue;
00213
00214 result = true;
00215 list->removeRef(current);
00216 conn->signalConnectionList()->removeRef(current);
00217 if (current->senderConn)
00218 current->senderConn->signalConnectionList()->removeRef(current);
00219 delete current;
00220 }
00221 return result;
00222 }
00223
00230 void
00231 DCOPSignals::removeConnections(DCOPConnection *conn, const QCString &obj)
00232 {
00233 DCOPSignalConnectionList *list = conn->_signalConnectionList;
00234 if (!list)
00235 return;
00236
00237 DCOPSignalConnection *next = 0;
00238
00239 for(DCOPSignalConnection *current = list->first(); current; current = next)
00240 {
00241 next = list->next();
00242
00243 if (!obj.isEmpty())
00244 {
00245 if ((current->senderConn == conn) && (current->senderObj != obj))
00246 continue;
00247
00248 if ((current->recvConn == conn) && (current->recvObj != obj))
00249 continue;
00250 }
00251
00252 if (current->senderConn && (current->senderConn != conn))
00253 current->senderConn->signalConnectionList()->removeRef(current);
00254
00255 if (current->recvConn != conn)
00256 current->recvConn->signalConnectionList()->removeRef(current);
00257
00258 DCOPSignalConnectionList *signalList = connections.find(current->signal);
00259 if (signalList)
00260 {
00261 signalList->removeRef(current);
00262 if (signalList->isEmpty())
00263 connections.remove(current->signal);
00264 }
00265 else
00266 {
00267 qDebug("Error: Signal Connection was not in signalList!\n");
00268 }
00269 list->removeRef(current);
00270 delete current;
00271 }
00272 }
00273
00274