/* We are called when the scroll list has potentially changed Updates the info in all windows of the scroll list (sets new text in window). */ void scroll_list_changed(scroll_list *sl){ int i; char *info; struct Window *pwin; for (i=0, pwin = sl->wl; i < sl->num_windows; pwin++, i++){ info = sl->info_text( info_pos(sl, i) ); win_new_text( pwin, info); } };
/* The position of the currently selected info is decremented, i. e. the selected window is moved up towards the top of the screen If we are already at the top of the window list, we must move the text lines down! */ void scroll_list_up(scroll_list *sl){ if (sl->sel_win > 0) sel_win_up(sl); else { // We want to scroll past the upper end of the window list if ( info_pos(sl, 0) > sl->first_pos){ // valid pos sl->first_shown_pos--; sl->range_set(sl->first_shown_pos, last_shown_pos(sl) ); scroll_list_changed(sl); }; }; };
/** Overloads default QWidget::paintEvent. Draws the actual * bandwidth graph. */ void RSPermissionMatrixWidget::paintEvent(QPaintEvent *) { //std::cerr << "In paint event!" << std::endl; /* Set current graph dimensions */ _rec = this->frameRect(); /* Start the painter */ _painter->begin(this); /* We want antialiased lines and text */ _painter->setRenderHint(QPainter::Antialiasing); _painter->setRenderHint(QPainter::TextAntialiasing); /* Fill in the background */ _painter->fillRect(_rec, QBrush(BACK_COLOR)); _painter->drawRect(_rec); // draw one line per friend. std::list<RsPeerId> ssllist ; rsPeers->getFriendList(ssllist) ; // sort list { // RSPermissionMatrixWidgets parent is ServicePermissionsPage which holds the checkbox ServicePermissionsPage *spp = dynamic_cast<ServicePermissionsPage*>(parentWidget()); if(spp != NULL) { // sort out offline peers if(spp->isHideOfflineChecked()) { RsPeerDetails peerDetails; for(std::list<RsPeerId>::iterator it = ssllist.begin(); it != ssllist.end();) { rsPeers->getPeerDetails(*it, peerDetails); switch (peerDetails.connectState) { case RS_PEER_CONNECTSTATE_OFFLINE: case RS_PEER_CONNECTSTATE_TRYING_TCP: case RS_PEER_CONNECTSTATE_TRYING_UDP: it = ssllist.erase(it); break; default: it++; break; } } } } // sort by name ssllist.sort(sortRsPeerIdByNameLocation); } RsPeerServiceInfo ownServices; rsServiceControl->getOwnServices(ownServices); // Display friend names at the beginning of each column const QFont& font(_painter->font()) ; QFontMetrics fm(font); int peer_name_size = 0 ; float line_height = 2 + fm.height() ; std::vector<QString> names ; for(std::list<RsPeerId>::const_iterator it(ssllist.begin());it!=ssllist.end();++it) { RsPeerDetails details ; rsPeers->getPeerDetails(*it,details) ; QString name = QString::fromUtf8(details.name.c_str()) + " (" + QString::fromUtf8(details.location.c_str()) + ")"; if(name.length() > 20) name = name.left(20)+"..." ; peer_name_size = std::max(peer_name_size, fm.width(name)) ; names.push_back(name) ; } QPen pen ; pen.setWidth(2) ; pen.setBrush(Qt::black) ; _painter->setPen(pen) ; int i=0; int x=5 ; int y=MATRIX_START_Y ; for(std::list<RsPeerId>::const_iterator it(ssllist.begin());it!=ssllist.end();++it,++i) { float X = MATRIX_START_X + peer_name_size - fm.width(names[i]) ; float Y = MATRIX_START_Y + (i+0.5)*ROW_SIZE + line_height/2.0f-2 ; _painter->drawText(QPointF(X,Y),names[i]) ; if(*it == _current_peer_id) _painter->drawLine(QPointF(X,Y+3),QPointF(X+fm.width(names[i]),Y+3)) ; y += line_height ; } matrix_start_x = 5 + MATRIX_START_X + peer_name_size ; // now draw the service names i=0 ; std::vector<int> last_width(10,0) ; for(std::map<uint32_t, RsServiceInfo>::const_iterator it(ownServices.mServiceList.begin());it!=ownServices.mServiceList.end();++it,++i) { QString name = QString::fromUtf8(it->second.mServiceName.c_str()) ; int text_width = fm.width(name) ; int X = matrix_start_x + COL_SIZE/2 - 2 + i*COL_SIZE - text_width/2; int height_index = 0 ; while(last_width[height_index] > X-5 && height_index < last_width.size()-1) ++height_index ; int Y = MATRIX_START_Y - ICON_SIZE_Y - 2 - line_height * height_index; last_width[height_index] = X + text_width ; // draw a half-transparent rectangle QBrush brush ; brush.setColor(QColor::fromHsvF(0.0f,0.0f,1.0f,0.8f)); brush.setStyle(Qt::SolidPattern) ; QPen pen ; pen.setWidth(2) ; if(_current_service_id == it->second.mServiceType) pen.setBrush(Qt::black) ; else pen.setBrush(Qt::gray) ; _painter->setPen(pen) ; QRect info_pos( X-5,Y-line_height-2, text_width + 10, line_height + 5) ; //_painter->fillRect(info_pos,brush) ; //_painter->drawRect(info_pos) ; _painter->drawLine(QPointF(X,Y+3),QPointF(X+text_width,Y+3)) ; _painter->drawLine(QPointF(X+text_width/2, Y+3), QPointF(X+text_width/2,MATRIX_START_Y+peer_ids.size()*ROW_SIZE - ROW_SIZE+5)) ; pen.setBrush(Qt::black) ; _painter->setPen(pen) ; _painter->drawText(QPointF(X,Y),name); } // Now draw the global switches. peer_ids.clear() ; for(std::list<RsPeerId>::const_iterator it(ssllist.begin());it!=ssllist.end();++it) peer_ids.push_back(*it) ; service_ids.clear() ; for(std::map<uint32_t, RsServiceInfo>::const_iterator sit(ownServices.mServiceList.begin());sit!=ownServices.mServiceList.end();++sit) service_ids.push_back(sit->first) ; static const std::string global_switch[2] = { ":/images/global_switch_off.png", ":/images/global_switch_on.png" } ; for(int i=0;i<service_ids.size();++i) { RsServicePermissions serv_perm ; rsServiceControl->getServicePermissions(service_ids[i],serv_perm) ; QPixmap pix(global_switch[serv_perm.mDefaultAllowed].c_str()) ; QRect position = computeNodePosition(0,i,false) ; position.setY(position.y() - ICON_SIZE_Y + 8) ; position.setX(position.x() + 3) ; position.setHeight(30) ; position.setWidth(30) ; _painter->drawPixmap(position,pix,QRect(0,0,30,30)) ; } // We draw for each service. static const std::string pixmap_names[4] = { ":/images/switch00.png", ":/images/switch01.png", ":/images/switch10.png", ":/images/switch11.png" } ; int n_col = 0 ; int n_col_selected = -1 ; int n_row_selected = -1 ; for(std::map<uint32_t, RsServiceInfo>::const_iterator sit(ownServices.mServiceList.begin());sit!=ownServices.mServiceList.end();++sit,++n_col) { RsServicePermissions service_perms ; rsServiceControl->getServicePermissions(sit->first,service_perms) ; // draw the default switch. // draw one switch per friend. int n_row = 0 ; for(std::list<RsPeerId>::const_iterator it(ssllist.begin());it!=ssllist.end();++it,++n_row) { RsPeerServiceInfo local_service_perms ; RsPeerServiceInfo remote_service_perms ; rsServiceControl->getServicesAllowed (*it, local_service_perms) ; rsServiceControl->getServicesProvided(*it,remote_service_perms) ; bool local_allowed = local_service_perms.mServiceList.find(sit->first) != local_service_perms.mServiceList.end() ; bool remote_allowed = remote_service_perms.mServiceList.find(sit->first) != remote_service_perms.mServiceList.end() ; QPixmap pix(pixmap_names[(local_allowed << 1) + remote_allowed].c_str()) ; bool selected = (sit->first == _current_service_id && *it == _current_peer_id) ; QRect position = computeNodePosition(n_row,n_col,selected) ; if(selected) { n_row_selected = n_row ; n_col_selected = n_col ; } _painter->drawPixmap(position,pix,QRect(0,0,ICON_SIZE_X,ICON_SIZE_Y)) ; } } // now display some info about current node. if(n_row_selected < peer_ids.size() && n_col_selected < service_ids.size()) { QRect position = computeNodePosition(n_row_selected,n_col_selected,false) ; // draw text info RsServicePermissions service_perms ; rsServiceControl->getServicePermissions(service_ids[n_col_selected],service_perms) ; QString service_name = tr("Service name:")+" "+QString::fromUtf8(service_perms.mServiceName.c_str()) ; QString service_default = service_perms.mDefaultAllowed?tr("Allowed by default"):tr("Denied by default"); QString peer_name = tr("Peer name:")+" " + names[n_row_selected] ; QString peer_id = tr("Peer Id:")+" "+QString::fromStdString(_current_peer_id.toStdString()) ; RsPeerServiceInfo pserv_info ; rsServiceControl->getServicesAllowed(_current_peer_id,pserv_info) ; bool locally_allowed = pserv_info.mServiceList.find(_current_service_id) != pserv_info.mServiceList.end(); bool remotely_allowed = false ; // default, if the peer is offline if(rsServiceControl->getServicesProvided(_current_peer_id,pserv_info)) remotely_allowed = pserv_info.mServiceList.find(_current_service_id) != pserv_info.mServiceList.end(); QString local_status = locally_allowed ?tr("Enabled for this peer") :tr("Disabled for this peer") ; QString remote_status = remotely_allowed?tr("Enabled by remote peer"):tr("Disabled by remote peer") ; if(!service_perms.mDefaultAllowed) local_status = tr("Switched Off") ; const QFont& font(_painter->font()) ; QFontMetrics fm(font); int text_size_x = 0 ; text_size_x = std::max(text_size_x,fm.width(service_name)); text_size_x = std::max(text_size_x,fm.width(peer_name)); text_size_x = std::max(text_size_x,fm.width(peer_id)); text_size_x = std::max(text_size_x,fm.width(local_status)); text_size_x = std::max(text_size_x,fm.width(remote_status)); // draw a half-transparent rectangle QBrush brush ; brush.setColor(QColor::fromHsvF(0.0f,0.0f,1.0f,0.8f)); brush.setStyle(Qt::SolidPattern) ; QPen pen ; pen.setWidth(2) ; pen.setBrush(Qt::black) ; _painter->setPen(pen) ; QRect info_pos( position.x() + 50, position.y() - 10, text_size_x + 10, line_height * 5 + 5) ; _painter->fillRect(info_pos,brush) ; _painter->drawRect(info_pos) ; // draw the text float x = info_pos.x() + 5 ; float y = info_pos.y() + line_height + 1 ; _painter->drawText(QPointF(x,y), service_name) ; y += line_height ; _painter->drawText(QPointF(x,y), peer_name) ; y += line_height ; _painter->drawText(QPointF(x,y), peer_id) ; y += line_height ; _painter->drawText(QPointF(x,y), remote_status) ; y += line_height ; _painter->drawText(QPointF(x,y), local_status) ; y += line_height ; } _max_height = MATRIX_START_Y + (peer_ids.size()+3) * ROW_SIZE ; _max_width = matrix_start_x + (service_ids.size()+3) * COL_SIZE ; /* Stop the painter */ _painter->end(); }
/* Returns the positional index corresponding to the selected window Used by the view to tell the controller which item the user selected */ int scroll_list_selected(scroll_list *sl){ return info_pos(sl, sl->sel_win); };