/*! \brief Save the positions of Peer Widgets * * Save the positions of all Peer Widgets to the settings. */ void XletSwitchBoard::savePositions() const { // qDebug() << Q_FUNC_INFO << m_peerhash.count(); QSettings * settings = b_engine->getSettings(); settings->beginGroup("layout"); QHashIterator<QString, PeerItem *> it(m_peerhash); while (it.hasNext()) { it.next(); const QString userid = it.key(); PeerItem *peeritem = it.value(); if (peeritem->getWidget()) { settings->setValue(userid, m_layout->getItemPosition(peeritem->getWidget())); } else { settings->remove(userid); } } settings->beginWriteArray("externalphone"); int i, index = 0; for (i=0;i<m_layout->count();i++) { QLayoutItem *item = m_layout->itemAt(i); if ((item) && (item->widget()) && ((item->widget()->inherits("ExternalPhonePeerWidget")) || (item->widget()->inherits("DetailedExternalPhonePeerWidget")))) { BasePeerWidget *w = static_cast<BasePeerWidget *>(item->widget()); settings->setArrayIndex(index++); settings->setValue("position", m_layout->getItemPosition(w)); settings->setValue("name", w->name()); settings->setValue("number", w->number()); } } settings->endArray(); settings->endGroup(); }
/*! \brief Receives drop events * * This method recieve drop events. It is currently used to * move PeerWidgets arount :) * * \sa dragEnterEvent() */ void XletSwitchBoard::dropEvent(QDropEvent *event) { // qDebug() << Q_FUNC_INFO; if (event->mimeData()->hasFormat(USERID_MIMETYPE)) { QString userid = event->mimeData()->data(USERID_MIMETYPE); if (m_peerhash.contains(userid)) { PeerItem *peeritem = m_peerhash[userid]; BasePeerWidget *peerwidget = peeritem->getWidget(); if (peerwidget) { m_layout->setItemPosition(peerwidget, m_layout->getPosInGrid(event->pos())); } else { peerwidget = addPeerWidget(peeritem, m_layout->getPosInGrid(event->pos())); } updateGeometry(); event->acceptProposedAction(); savePositions(); update(); } } else if (event->mimeData()->hasFormat(NUMBER_MIMETYPE)) { QString number = event->mimeData()->data(NUMBER_MIMETYPE); BasePeerWidget *w = getExternalPhonePeerWidget(number); if (w) { m_layout->setItemPosition(w, m_layout->getPosInGrid(event->pos())); updateGeometry(); event->acceptProposedAction(); savePositions(); update(); } } }
bool SearchPanel::isShown(const QString &xuserid) const { PeerItem *peer = m_peerhash.value(xuserid, NULL); if (peer) { if (BasePeerWidget *widget = peer->getWidget()) { return widget->isVisible(); } } return false; }
/*! \brief remove a PeerItem * * Find the peer and remove it from the list * and the widget. * * \sa updatePeer * \sa removePeers */ void XletSwitchBoard::removePeer(const QString &userid) { // qDebug() << Q_FUNC_INFO << userid; if (m_peerhash.contains(userid)) { PeerItem *peeritem = m_peerhash.value(userid); BasePeerWidget *peerwidget = peeritem->getWidget(); m_layout->removeWidget(peerwidget); peerwidget->deleteLater(); delete m_peerhash.take(userid); update(); } }
/*! \brief update display of user informations * * Update all what need to be displayed about this user. * PeerItem is created if needed. * Display the PeerWidget if needed. */ void XletSwitchBoard::updateUser(UserInfo *ui) { // qDebug() << Q_FUNC_INFO << ui->toString(); QString userid = ui->userid(); PeerItem *peeritem = NULL; if (m_peerhash.contains(userid)) { peeritem = m_peerhash.value(userid); } else { peeritem = new PeerItem(ui); m_peerhash.insert(userid, peeritem); QSettings *settings = b_engine->getSettings(); settings->beginGroup("layout"); QPoint pos = settings->value(userid, QPoint(-1, -1)).toPoint(); settings->endGroup(); if (pos.x() >= 0) { addPeerWidget(peeritem, pos); } } peeritem->updateStatus(); update(); }
/*! \brief remove all peers * * remove all peers and widget. * * \sa removePeer */ void XletSwitchBoard::removePeers(void) { // qDebug() << Q_FUNC_INFO; QHashIterator<QString, PeerItem *> peeriter(m_peerhash); while (peeriter.hasNext()) { peeriter.next(); PeerItem *peeritem = peeriter.value(); //PeerWidget * peerwidget = peeritem->getWidget(); BasePeerWidget *peerwidget = peeritem->getWidget(); if (peerwidget != NULL) { m_layout->removeWidget(peerwidget); // this disconnect() step takes time, whether explicitly or implicitly, // so we should be careful to avoid too much connect's (anyway) disconnect(peerwidget, SIGNAL(removeFromPanel()), this, SLOT(removePeerFromLayout()) ); peerwidget->deleteLater(); } delete peeritem; } m_peerhash.clear(); update(); }
/*! \brief remove the peer from the layout * * the peer is moved to position (-1, -1) so it * wont be displayed anymore * * \sa dropEvent() */ void XletSwitchBoard::removePeerFromLayout() { const QString userid = sender()->property("userid" ).toString(); // qDebug() << Q_FUNC_INFO << userid << m_peerhash.keys(); if (m_peerhash.contains(userid)) { PeerItem *peeritem = m_peerhash[userid]; BasePeerWidget *peerwidget = peeritem->getWidget(); m_layout->removeWidget(peerwidget); m_layout->setItemPosition(peerwidget, QPoint(-1, -1)); //savePositions(); // this disconnect() step takes time, whether explicitly or implicitly, // so we should be careful to avoid too much connect's (anyway) disconnect(peerwidget, SIGNAL(removeFromPanel()), this, SLOT(removePeerFromLayout())); peerwidget->deleteLater(); peeritem->setWidget(NULL); update(); } else { m_layout->removeWidget(static_cast<QWidget *>(sender())); sender()->deleteLater(); } }
void PeerConnector::HandleNoDegree( data_input_stream& is, const PACKET_PEER_INFO& packetPeerInfo, bool isTCP ) { PPRedirectInfo redirectPacket; is >> redirectPacket; if ( !is ) return; VIEW_DEBUG("HandleNoDegree " << make_tuple( packetPeerInfo.Address, packetPeerInfo.OuterAddress ) << " " << redirectPacket.Peers.size() ); m_ipPool.AddConnectFailed(packetPeerInfo.OuterAddress, isTCP); PEER_CORE_INFO coreInfo; coreInfo.Clear(); for (UINT8 index = 0; index < redirectPacket.Peers.size(); ++index) { const REDIRECT_PEER_INFO& peer = redirectPacket.Peers[index]; //VIEW_INFO("Redirect " << peer.Address << " " << peer.Status.UploadBWLeft << " Qos=" << peer.Status.Qos << " DL=" << (int)peer.Status.DegreeLeft << " DO=" << peer.Status.OutDegree << " DI=" << peer.Status.InDegree << " SP=" << peer.Status.SkipPercent ); PEER_ADDRESS targetAddr ; if ( peer.OuterAddress.IP == m_NetInfo->GetOuterIP() ) // 外部IP相同,取内网IP连接,局域网连接 { targetAddr = peer.Address; } else if ( peer.OuterAddress.IsValid() ) // 外网地址可用,取外网地址 { targetAddr = peer.OuterAddress; } else // 没有外网地址可用,只好取内网地址 { targetAddr = peer.Address; } LIVE_ASSERT( targetAddr.IsValid() ); /* if ( false == peer.OuterAddress.IsValid() ) { // 如果OuterAddress无效(可能是还没有获取到外部ip和端口),使用内部地址代替 targetAddr = peer.Address; LIVE_ASSERT( false ); } else if ( peer.OuterAddress.IP == m_NetInfo->OuterAddress.IP ) { // 外部IP和我的外部IP相同,此peer跟我处于同一内网,使用内部地址连接 targetAddr = peer.Address; } else { targetAddr = peer.OuterAddress; } LIVE_ASSERT( 0 != targetAddr.UdpPort || 0 != targetAddr.TcpPort ); */ m_ipPool.AddCandidate(targetAddr, coreInfo, CANDIDATE_FROM_REDIRECT); // 检查剩余度是否不足 if ( m_PeerManager.GetDegreeLeft() < 0 ) return; // 检查出度是否已经过大 if ( m_PeerManager.GetStatistics().Degrees.All.Out + 3 > m_PeerManager.GetMaxLocalPeerCount() ) return; /// 检查pending连接是否已经过多 if ( IsBusy() ) return; PeerItem peerItem; peerItem.Init(); peerItem.CanDetect = true; peerItem.Info.Address = targetAddr; PeerConnectParam param(peerItem, false, m_PeerManager.GetConnectTimeout(), false); if ( targetAddr.TcpPort == 0 && targetAddr.UdpPort == 0 ) // 两个端口都没有,错误 { VIEW_ERROR( "PeerConnector::HandleNoDegree - targetAddr error. inner address: " << peer.Address << " outer address: " << peer.OuterAddress ); } else if ( targetAddr.TcpPort == 0 ) // 没有TCP端口 { this->ConnectUDP( targetAddr, param ); } else if ( targetAddr.UdpPort == 0 ) // 没有UDP端口,只能连接TCP { this->ConnectTCP( targetAddr, 0, param ); } else if (peer.ConnectionType == 0) // 两个端口都存在 { // tcp this->ConnectTCP( targetAddr, 0, param ); } else if ( peer.ConnectionType == 1 ) { // udp this->ConnectUDP( targetAddr, param ); } else { VIEW_ERROR( "PeerConnector::HandleNoDegree invalid peer connection type " << peer.ConnectionType << " " << make_tuple( peer.Address, peer.OuterAddress, targetAddr ) << " " << packetPeerInfo.OuterAddress ); } } }
/*! \brief update the list of Persons displayed */ void SearchPanel::updateDisplay() { if (m_live_reload_enabled == false) { return; } // max number of peers displayed on the search panel unsigned maxdisplay = maxDisplay(); // number of columns (0 = auto) unsigned ncolumns = 0; ncolumns = m_scrollarea->width() / (PeerWidget::max_width + 2 * SearchPanel::peer_spacing); // Prevent arithmetic exception if (ncolumns == 0) { ncolumns = 1; } // first hide/delete everyonedisplayed QHashIterator<QString, PeerItem *> i(m_peerhash); while (i.hasNext()) { i.next(); PeerItem *peeritem = i.value(); BasePeerWidget *peerwidget = peeritem->getWidget(); if ((peerwidget != NULL) && (m_peerlayout->indexOf(peerwidget) > -1)) { m_peerlayout->removeWidget(peerwidget); peerwidget->hide(); peeritem->setWidget(NULL); peerwidget->deleteLater(); } } // then display all users whose name match the search pattern unsigned naff = 0; i.toFront(); while (i.hasNext()) { i.next(); PeerItem * peeritem = i.value(); BasePeerWidget * peerwidget = peeritem->getWidget(); const UserInfo * userinfo = peeritem->userinfo(); if (userinfo == NULL) continue; if (peeritem->matchPattern(m_searchpattern) && (naff < maxdisplay)) { if (peerwidget == NULL) { peerwidget = new PeerWidget(userinfo); if (! userinfo->agentid().isEmpty()) { peerwidget->updateAgentConfig(userinfo->xagentid()); peerwidget->updateAgentStatus(userinfo->xagentid()); } foreach (const QString &xphoneid, userinfo->phonelist()) { peerwidget->updatePhoneConfig(xphoneid); peerwidget->updatePhoneStatus(xphoneid); } peeritem->setWidget(peerwidget); peeritem->updateDisplayedStatus(); peeritem->updateDisplayedName(); m_peerlayout->addWidget(peerwidget, naff / ncolumns, naff % ncolumns); naff++; peerwidget->show(); } } }