int main(void) { if( !initSockets(true) ) return 1; IConnection * tcpConnection = new TCPConnection(); if(static_cast<TCPConnection*>(tcpConnection)->connect(Socket::localIP(), 1024)) std::cout << "Connected!" << std::endl; else std::cout << "Error connecting! #" << WSAGetLastError() << std::endl; if( 14 != tcpConnection->send((ubyte*)"hello, world!", 14) ) std::cout << "send failed!" << std::endl; std::cout << std::endl << tcpConnection->connectionInfo() << std::endl; // wait for input. std::getchar(); static_cast<TCPConnection*>(tcpConnection)->close(); // cleanup. cleanSockets(); return 0; }
int main(int argc, const char * argv[]) { using namespace mlclient; using namespace mlclient::utilities; mlclient::reconfigureLogging(argc,argv); LOG(DEBUG) << "Running search..."; if (argc < 2) { std::cout << "Must specify a search string text as first parameter" << std::endl; std::cout << "Usage: " << argv[0] << " <querytext>" << std::endl; std::cout << "Example Usage: " << argv[0] << " wibble" << std::endl; return 1; } IConnection* ml = ConnectionFactory::getConnection(); SearchDescription desc; desc.setQueryText(argv[1]); Response* response = ml->search(desc); LOG(DEBUG) << " Response Type: " << response->getResponseType(); LOG(DEBUG) << " Response Code: " << response->getResponseCode(); LOG(DEBUG) << " Response Content: " << response->getContent(); std::cout << "Search Results:-" << std::endl; std::cout << response->getContent() << std::endl; std::cout << "search complete" << std::endl; delete response; delete ml; return 0; }
bool master_service::on_accept(acl::aio_socket_stream* client) { if (0) logger("connect from %s, fd %d", client->get_peer(true), client->sock_handle()); acl_non_blocking(client->sock_handle(), ACL_BLOCKING); // 根据客户端连接服务端口号的不同来区分不同的服务应用协议 const char* local = client->get_local(true); if (acl_strrncasecmp(local, var_cfg_backend_service, strlen(var_cfg_backend_service)) == 0) { // 创建服务对象处理来自于后端服务模块的请求 IConnection* conn = new ServerConnection(client); conn->run(); return true; } else { // 创建对象处理来自于前端客户端模块的请求 IConnection* conn = new ClientConnection(client, var_cfg_conn_expired); conn->run(); return true; } return true; }
void ApiHandler::IpcEditorGetLineRange(EditorCtrl& editor, IConnection& conn) { const hessian_ipc::Call& call = *conn.get_call(); const unsigned int lineid = call.GetParameter(1).GetInt(); if (lineid > editor.GetLineCount()) return; // fault const interval iv = editor.GetLineExtent(lineid); hessian_ipc::Writer& writer = conn.get_reply_writer(); writer.write_reply(iv); }
void ApiHandler::IpcEditorGetLineText(EditorCtrl& editor, IConnection& conn) { const hessian_ipc::Call& call = *conn.get_call(); const unsigned int lineid = call.GetParameter(1).GetInt(); if (lineid > editor.GetLineCount()) return; // fault vector<char> text; editor.GetLine(lineid, text); hessian_ipc::Writer& writer = conn.get_reply_writer(); writer.write_reply(text); }
int FriendsList::getFriendsCount() { int result = 0; int len = size(); for (int i = 0; i < len; i++) { IConnection * con = operator[](i); if (con->getState() == 1) result ++; } return result; }
void ApiHandler::IpcEditorDeleteRange(EditorCtrl& editor, IConnection& conn) { const hessian_ipc::Call& call = *conn.get_call(); // Get the inset position const size_t start = call.GetParameter(1).GetInt(); const size_t end = call.GetParameter(2).GetInt(); if (end > editor.GetLength() || start > end) return; // fault: invalid positions // Delete the range const size_t byte_len = editor.RawDelete(start, end); // Write the reply hessian_ipc::Writer& writer = conn.get_reply_writer(); writer.write_reply(byte_len); }
void ApiHandler::IpcEditorSelect(EditorCtrl& editor, IConnection& conn) { const hessian_ipc::Call& call = *conn.get_call(); const int v2 = call.GetParameter(1).GetInt(); const int v3 = call.GetParameter(2).GetInt(); if (v2 != v3) { editor.Select(v2, v3); editor.MakeSelectionVisible(); } editor.SetPos(v3); editor.ReDraw(); hessian_ipc::Writer& writer = conn.get_reply_writer(); writer.write_reply(true); }
void ApiHandler::IpcGetActiveEditor(IConnection& conn) { EditorCtrl* editor = m_app.GetActiveEditorCtrl(); const int id = -editor->GetId(); hessian_ipc::Writer& writer = conn.get_reply_writer(); writer.write_reply_handle(id); }
void ApiHandler::IpcEditorGetText(EditorCtrl& editor, IConnection& conn) { vector<char> text; editor.GetText(text); hessian_ipc::Writer& writer = conn.get_reply_writer(); writer.write_reply(text); }
void ApiHandler::IpcEditorPrompt(EditorCtrl& editor, IConnection& conn) { const hessian_ipc::Call& call = *conn.get_call(); // Get the title const hessian_ipc::Value& v2 = call.GetParameter(1); const string& t = v2.GetString(); const wxString title(t.c_str(), wxConvUTF8, t.size()); // Show Prompt WindowEnabler we; // otherwise dlg wont be able to return focus const wxString text = wxGetTextFromUser(title, _("Input text"), wxEmptyString, &editor); const wxCharBuffer str = text.ToUTF8(); hessian_ipc::Writer& writer = conn.get_reply_writer(); writer.write_reply(str.data()); }
void ApiHandler::IpcEditorGetChangesSince(EditorCtrl& editor, IConnection& conn) { const hessian_ipc::Call& call = *conn.get_call(); // Get the version handle const size_t versionHandle = call.GetParameter(1).GetInt(); ConnectionState& connState = GetConnState(conn); if (versionHandle >= connState.docHandles.size()) return; // fault: invalid handle const doc_id& di = connState.docHandles[versionHandle]; // Get diff vector<size_t> changedlines; editor.GetLinesChangedSince(di, changedlines); // Return changed lines hessian_ipc::Writer& writer = conn.get_reply_writer(); writer.write_reply(changedlines); }
void ApiHandler::IpcLog(IConnection& conn) { // Get the text to insert const hessian_ipc::Call& call = *conn.get_call(); const hessian_ipc::Value& v = call.GetParameter(0); const string& t = v.GetString(); const wxString text(t.c_str(), wxConvUTF8, t.size()); wxLogDebug(text); }
void ClientConnectionPolicy::ProcessNewMessage(IConnection& server , RequestInfoPtr requestInfo) { server.ConnectAsync(requestInfo->Host(), requestInfo->Port()); PendingRequests& requests = connectionManager_.Requests(); requests.push(std::move(requestInfo)); }
bool master_service::on_accept(acl::aio_socket_stream* client) { if (0) logger("connect from %s, fd %d", client->get_peer(true), client->sock_handle()); acl_non_blocking(client->sock_handle(), ACL_BLOCKING); IConnection* conn; // 根据客户端连接服务端口号的不同来区分不同的服务应用协议 const char* local = client->get_local(true); if (acl_strrncasecmp(local, var_cfg_backend_service, strlen(var_cfg_backend_service)) == 0) { // 创建服务对象处理来自于后端服务模块的请求 conn = new ServerConnection(client); } else if (acl_strrncasecmp(local, var_cfg_status_service, strlen(var_cfg_status_service)) == 0) { const char* ip = client->get_peer(); if (ip == NULL || *ip == 0) { logger_error("can't get peer ip"); return false; } if (allow_list::get_instance().allow_manager(ip) == false) { logger_warn("deny manager ip: %s", ip); return false; } // 创建服务对象处理状态汇报的请求 conn = new StatusConnection(client); } else // 创建对象处理来自于前端客户端模块的请求 conn = new ClientConnection(client, var_cfg_conn_expired); conn->run(); return true; }
void ApiHandler::IpcEditorShowCompletions(EditorCtrl& editor, IConnection& conn) { const hessian_ipc::Call& call = *conn.get_call(); const hessian_ipc::Value& v2 = call.GetParameter(1); const hessian_ipc::List& completions = v2.AsList(); if (!completions.empty()) { wxArrayString comp; for (size_t i = 0; i < completions.size(); ++i) { const string& s = completions.get(i).GetString(); const wxString text(s.c_str(), wxConvUTF8, s.size()); comp.push_back(text); } editor.ShowCompletionPopup(comp); } hessian_ipc::Writer& writer = conn.get_reply_writer(); writer.write_reply_null(); }
void ApiHandler::IpcEditorGetScope(EditorCtrl& editor, IConnection& conn) { const deque<const wxString*> s = editor.GetScope(); vector<string> scopes; for (deque<const wxString*>::const_iterator p = s.begin(); p != s.end(); ++p) { scopes.push_back((*p)->ToUTF8().data()); } hessian_ipc::Writer& writer = conn.get_reply_writer(); writer.write_reply(scopes); }
void ApiHandler::IpcEditorGetVersionId(EditorCtrl& editor, IConnection& conn) { const doc_id id = editor.GetLastStableDocID(); // create handle for doc_id ConnectionState& connState = GetConnState(conn); const size_t handle = connState.docHandles.size(); connState.docHandles.push_back(id); hessian_ipc::Writer& writer = conn.get_reply_writer(); writer.write_reply(handle); }
// 获取到角色数据之后,回调此函数 void PlayerMng::AchievePlayerData(const roledata::PBRoleTotalInfo& roleData, const string& strDesc) { map<string, Player*>::iterator playerIt = m_playerInfoMap.find(roleData.baseinfo().ptname()); if (playerIt == m_playerInfoMap.end()) { ERRORLOG("cannot find player, ptname=[" << roleData.baseinfo().ptname() << "],desc=[" << strDesc << "]"); return; } Player* pPlayer = playerIt->second; if (!pPlayer) { ERRORLOG("player is NULL"); return; } IConnection* pClientConn = pPlayer->GetPlayerConnection(); if (!pClientConn) { ERRORLOG("player client connection is NULL."); return; } if (!pClientConn->IsConnected()) { ERRORLOG("player client connection=[" << pClientConn <<"] is disconnect."); return; } pPlayer->GetRoleTotalInfo(roleData); pPlayer->SetPlayerState(PLAYER_ONLINE); uint32_t ID = pPlayer->GetPlayerID(); m_playerIdMap.insert(make_pair(pPlayer->GetPlayerID(), pPlayer)); TRACELOG("Achieve player data, ID=[" << ID << "], ptname=[" << pPlayer->PtName() << "] " << strDesc); // 玩家数据可能已经被修改了 roledata::PBRoleTotalInfo newRoleTotalData; pPlayer->SerializeToPB(newRoleTotalData); // 将数据返回给客户端 _SendPlayerDataToClient(pClientConn, newRoleTotalData); }
int main(int argc, const char * argv[]) { using namespace mlclient; using namespace mlclient::utilities; mlclient::reconfigureLogging(argc,argv); std::cout << "Running getdoc..." << std::endl; LOG(DEBUG) << "Running getdoc..."; IConnection* ml = ConnectionFactory::getConnection(); std::string uri = "/some/doc.json"; if (argc > 1) { uri = std::string(argv[1]); } const Response* rp = ml->getDocument(uri); // MUST keep local reference to unique_ptr for this to work!!! ResponseType rt = rp->getResponseType(); std::cout << "Response type: " << rt << std::endl; LOG(DEBUG) << "Response type: " << rt; if (ResponseType::JSON == rt) { std::cout << "This is JSON doc " << uri << ": " << std::endl; CppRestJsonHelper::fromResponse(*rp).serialize(std::cout); std::cout << std::endl; LOG(DEBUG) << "This is JSON doc " << uri << ": "; CppRestJsonHelper::fromResponse(*rp).serialize(LOG(DEBUG)); } if (ResponseType::XML == rt) { std::cout << "This is XML doc " << uri << ": " << std::endl; PugiXmlHelper::fromResponse(*rp)->save(std::cout); std::cout << std::endl; LOG(DEBUG) << "This is XML doc " << uri << ": "; PugiXmlHelper::fromResponse(*rp)->save(LOG(DEBUG)); // TODO check this works as expected } std::cout << "getdoc complete" << std::endl; LOG(DEBUG) << "getdoc complete"; return 0; }
void ApiHandler::IpcEditorWatchChanges(EditorCtrl& editor, IConnection& conn) { // Register notifier const unsigned int notifier_id = GetNextNotifierId(); m_notifiers[notifier_id] = &conn; // Add to watch list const EditorWatch ew = {WATCH_EDITOR_CHANGE, editor.GetId(), editor.GetChangeToken(), notifier_id}; m_editorWatchers.push_back(ew); // Return notifier id hessian_ipc::Writer& writer = conn.get_reply_writer(); writer.write_reply(notifier_id); }
void ApiHandler::IpcEditorShowInputLine(EditorCtrl& , IConnection& conn) { const hessian_ipc::Call& call = *conn.get_call(); // Get caption const hessian_ipc::Value& v2 = call.GetParameter(1); const string& t = v2.GetString(); const wxString caption(t.c_str(), wxConvUTF8, t.size()); // Register notifier const unsigned int notifier_id = GetNextNotifierId(); m_notifiers[notifier_id] = &conn; // Show input line EditorFrame* frame = m_app.GetTopFrame(); if (!frame) return; frame->ShowInputPanel(notifier_id, caption); // Return notifier id hessian_ipc::Writer& writer = conn.get_reply_writer(); writer.write_reply(notifier_id); }
void ApiHandler::IpcEditorInsertAt(EditorCtrl& editor, IConnection& conn) { // Get the insert position const hessian_ipc::Call& call = *conn.get_call(); const size_t pos = call.GetParameter(1).GetInt(); if (pos > editor.GetLength()) return; // fault: invalid position // Get the text to insert const hessian_ipc::Value& v3 = call.GetParameter(2); const string& t = v3.GetString(); const wxString text(t.c_str(), wxConvUTF8, t.size()); // Insert the text // TODO: adjust selections const unsigned int cpos = editor.GetPos(); const size_t byte_len = editor.RawInsert(pos, text); if (cpos >= pos) editor.SetPos(cpos + byte_len); editor.ReDraw(); // Write the reply hessian_ipc::Writer& writer = conn.get_reply_writer(); writer.write_reply(byte_len); }
void PlayerMng::CreateRoleResult(const string& strPtName, int32_t nErrCode) { Player* pPlayer = GetPlayer(strPtName); if (!pPlayer) { ERRORLOG("create role ptname=[" << strPtName << "] result, cannot find player"); return; } IConnection* pClientConn = pPlayer->GetPlayerConnection(); if (!pClientConn || !pClientConn->IsConnected()) { ERRORLOG("create role ptname=[" << strPtName << "] result, client connection invalid"); return; } ctos::ResponseCreateRole createRoleAck; createRoleAck.set_errcode(nErrCode); string strMessage; BuildResponseProto<ctos::ResponseCreateRole>(createRoleAck, strMessage, ID_ACK_ResponseCreateRole); pClientConn->SendMsg(strMessage.c_str(), strMessage.size()); return; }
void ApiHandler::IpcEditorInsertTabStops(EditorCtrl& editor, IConnection& conn) { const hessian_ipc::Call& call = *conn.get_call(); const hessian_ipc::Value& v2 = call.GetParameter(1); const hessian_ipc::List& tabstops = v2.AsList(); if (!tabstops.empty()) { SnippetHandler& sh = editor.GetSnippetHandler(); sh.Clear(); for (size_t i = 0; i < tabstops.size(); ++i) { const hessian_ipc::List& t = tabstops.get(i).AsList(); const interval iv(t.get(0).GetInt(), t.get(1).GetInt()); const string& s = t.get(2).GetString(); const wxString text(s.c_str(), wxConvUTF8, s.size()); sh.AddTabStop(iv, text); } sh.NextTab(); editor.ReDraw(); } hessian_ipc::Writer& writer = conn.get_reply_writer(); writer.write_reply_null(); }
void ApiHandler::OnIpcCall(wxCommandEvent& event) { IConnection* conn = (IConnection*)event.GetClientData(); if (!conn) return; const hessian_ipc::Call* call = conn->get_call(); hessian_ipc::Writer& writer = conn->get_reply_writer(); if (!call) return; const string& m = call->GetMethod(); const wxString method(m.c_str(), wxConvUTF8, m.size()); wxLogDebug(wxT("IPC: %s"), method.c_str()); // Call the function (if it exists) bool methodFound = true; if (call->IsObjectCall()) { const hessian_ipc::Call& call = *conn->get_call(); const hessian_ipc::Value& v1 = call.GetParameter(0); const int editorId = -v1.GetInt(); EditorCtrl* editor = m_app.GetEditorCtrl(editorId); if (!editor) { writer.write_fault(hessian_ipc::NoSuchObjectException, "Unknown object"); conn->reply_done(); return; } map<string, PIpcEdFun>::const_iterator p = m_ipcEditorFunctions.find(m.c_str()); if (p != m_ipcEditorFunctions.end()) { try { (this->*p->second)(*editor, *conn); } catch (exception& e) { writer.write_fault(hessian_ipc::ServiceException, e.what()); conn->reply_done(); return; } } else { eMacroCmd cmd(method); for (size_t i = 1; i < call.GetParameterCount(); ++i) { const hessian_ipc::Value& v = call.GetParameter(i); if (v.IsBoolean()) cmd.AddArg(v.GetBoolean()); else if (v.IsInt()) cmd.AddArg(v.GetInt()); else if (v.IsString()) { const string& arg = v.GetString(); const wxString argstr(arg.c_str(), wxConvUTF8, arg.size()); cmd.AddArg(argstr); } else wxASSERT(false); } const wxVariant reply = editor->PlayCommand(cmd); if (reply.GetName() == wxT("Unknown method")) methodFound = false; else editor->ReDraw(); //TODO: write variant writer.write_reply_null(); } } else { map<string, PIpcFun>::const_iterator p = m_ipcFunctions.find(m.c_str()); if (p != m_ipcFunctions.end()) { try { (this->*p->second)(*conn); } catch (exception& e) { writer.write_fault(hessian_ipc::ServiceException, e.what()); conn->reply_done(); return; } } else methodFound = false; } if (!methodFound) { writer.write_fault(hessian_ipc::NoSuchMethodException, "Unknown method"); } // Notify connection that it can send the reply (threadsafe) conn->reply_done(); }
friend inline bool operator< ( const IConnection & lhs, const IConnection & rhs ) { return & lhs.get() < & rhs.get(); }
/*! * \param name Window name * \param type Window type (see constants.h for WT_*) * \param parent Parent ID (typically connection ID) * \param activate Activate window on creation * * Creates a new subwindow.\n * Specify Parent 0 if it's a custom (scriptable window).\n * DCC windows sets their parent to the IConnection that created it. It won't be a child of this IConnection though. * \return -1 if failed, otherwise Window ID */ int IdealIRC::CreateSubWindow(QString name, int type, int parent, bool activate) { if (WindowExists(name, parent) == true) return -1; qDebug() << "Creating new subwindow type " << type << " name " << name; IWin *s; if ((type >= WT_DCCSEND) && (type <= WT_DCCCHAT)) { IConnection *c = conlist.value(parent, NULL); s = new IWin(ui->mdiArea, name, type, &conf, &scriptParent, c); parent = 0; } else s = new IWin(ui->mdiArea, name, type, &conf, &scriptParent); IConnection *connection = conlist.value(parent, NULL); if (type == WT_STATUS) { qDebug() << "Window is status, new connection added with id " << s->getId(); connection = new IConnection(this, &chanlist, s->getId(), &conf, &scriptParent, &wsw); connection->setActiveInfo(&activeWname, &activeConn); connect(connection, SIGNAL(connectionClosed()), this, SLOT(connectionClosed())); connect(connection, SIGNAL(connectedToIRC()), this, SLOT(connectionEstablished())); connect(connection, SIGNAL(RequestTrayMsg(QString,QString)), this, SLOT(trayMessage(QString,QString))); } qDebug() << "Connection added, setting pointers"; s->setConnectionPtr(connection); if (connection != NULL) s->setSortRuleMap(connection->getSortRuleMapPtr()); qDebug() << "Pointers set, setting up mdiSubWindow"; QMdiSubWindow *previous = ui->mdiArea->currentSubWindow(); QMdiSubWindow *sw = ui->mdiArea->addSubWindow(s, Qt::SubWindow); qDebug() << "Pointer to subwindow: " << sw; qDebug() << "Icon..."; // Add icon to window QString ico = ":/window/gfx/custom.png"; // Default to this. if (type == WT_PRIVMSG) ico = ":/window/gfx/query.png"; if (type == WT_CHANNEL) ico = ":/window/gfx/channel.png"; if (type == WT_STATUS) ico = ":/window/gfx/status.png"; sw->setWindowIcon(QIcon(ico)); qDebug() << "Treeitem..."; QTreeWidgetItem *treeitem = GetWidgetItem(parent); if (treeitem == NULL) treeitem = new QTreeWidgetItem(ui->treeWidget); else treeitem = new QTreeWidgetItem(treeitem); treeitem->setIcon(0, QIcon(ico)); treeitem->setText(0, name); treeitem->setToolTip(0, name); qDebug() << "subwindow_t instance..."; subwindow_t wt; wt.connection = connection; wt.parent = parent; wt.subwin = sw; wt.treeitem = treeitem; wt.type = type; wt.wid = s->getId(); wt.widget = s; wt.highlight = HL_NONE; qDebug() << "Adding subwindow_t to winlist..."; winlist.insert(s->getId(), wt); wsw.addWindow(type, name, wt.wid, parent); sw->setGeometry(0, 0, 500, 400); if (type == WT_STATUS) { qDebug() << "Adding connection to the list..."; // The Connection class ID is the exact same ID as the status window ID. conlist.insert(s->getId(), connection); treeitem->setExpanded(true); connection->addWindow("STATUS", wt); connect(connection, SIGNAL(RequestWindow(QString,int,int,bool)), this, SLOT(CreateSubWindow(QString,int,int,bool))); connect(connection, SIGNAL(HighlightWindow(int,int)), this, SLOT(Highlight(int,int))); }
/*! * \param wid Window ID * * Runs when the specified Window ID is closed. */ void IdealIRC::subWinClosed(int wid) { subwindow_t empty; empty.wid = -1; subwindow_t sw = winlist.value(wid, empty); if (sw.wid == -1) return; // Nope. if (sw.type == WT_STATUS) { int statusCount = 0; QHashIterator<int,subwindow_t> i(winlist); while (i.hasNext()) if (i.next().value().type == WT_STATUS) ++statusCount; if (statusCount <= 1) return; // Nope. } std::cout << "Closing " << sw.widget->objectName().toStdString().c_str() << " (" << wid << ")" << std::endl; scriptParent.resetMenuPtrList(); if (sw.type == WT_STATUS) { // Closing a status window. QList<QMdiSubWindow*> closeList; // List of subwindows for this status to close QHashIterator<int,subwindow_t> i(winlist); // Iterate all windows IConnection *con = conlist.value(wid); // Remember window id of status is always equal to connection id. KISS! while (i.hasNext()) { i.next(); subwindow_t s = i.value(); // This item may not be a subwindow of the status that's closing. if (s.parent == wid) { // This item is a child of the status closeList.push_back(s.subwin); con->freeWindow( s.widget->objectName() ); } } if (con->isSocketOpen()) con->closeConnection(); // Begin closing the socket. // Close all its subwindows int count = closeList.count()-1; std::cout << " count : " << count << std::endl; for (int i = 0; i <= count; i++) { QMdiSubWindow *w = closeList.at(i); w->close(); } con->freeWindow("STATUS"); // Free status window lastly if (! con->isSocketOpen()) delete con; // Socket wasn't open, delete connection object } else { IConnection *con = conlist.value(sw.parent, NULL); if (con != NULL) con->freeWindow( sw.widget->objectName() ); winlist.remove(sw.wid); } if (sw.type == WT_CHANNEL) { IConnection *con = conlist.value(sw.parent); con->sockwrite("PART :" + sw.widget->objectName() ); } if (sw.type == WT_STATUS) wsw.delGroup(sw.wid); else wsw.delWindow(sw.wid); ui->treeWidget->removeItemWidget(sw.treeitem, 0); delete sw.treeitem; delete sw.widget; winlist.remove(wid); /** @note Do we need to delete the other pointers from subwindow_t ? **/ }
void IdealIRC::closeEvent(QCloseEvent *e) { if (connectionsRemaining > 0) { e->ignore(); // Still waiting for connections to close... return; } if (connectionsRemaining == -1) { // See if there is any connections active, if so, confirm on exit. QHashIterator<int,IConnection*> i(conlist); bool hasActive = false; while (i.hasNext()) { IConnection *c = i.next().value(); if (c != NULL) if (c->isOnline()) hasActive = true; if (hasActive) break; } if (hasActive) { int b = QMessageBox::question(this, tr("Confirm exit"), tr("There's connections active.\r\nDo you want to exit IdealIRC?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); if (b == QMessageBox::No) { e->ignore(); return; } } } // Save config prior to exit. conf.showToolBar = ui->toolBar->isVisible(); conf.showTreeView = (ui->treeWidget->width() > 0); conf.showButtonbar = wsw.getToolbar()->isVisible(); conf.maximized = isMaximized(); conf.save(); if (connectionsRemaining == 0) { e->accept(); // All connections closed, exit. return; } // Iterate through the connections and find the active ones and close them. // Remove and clean up their children too (windows and status) QHashIterator<int,IConnection*> ic(conlist); QList<IConnection*> cl; while (ic.hasNext()) { ic.next(); IConnection *con = ic.value(); if (con->isSocketOpen()) { if (connectionsRemaining == -1) connectionsRemaining = 0; ++connectionsRemaining; cl.push_back(con); } } readyToClose = false; for (int i = 0; i <= cl.count()-1; i++) cl[i]->closeConnection(true); readyToClose = true; if (! close()) // final close attempt e->ignore(); else e->accept(); }