SpikeStream Application Library
0.2
|
00001 //SpikeStream includes 00002 #include "Globals.h" 00003 #include "NetworkDisplay.h" 00004 #include "NeuronGroupModel.h" 00005 #include "SpikeStreamException.h" 00006 using namespace spikestream; 00007 00008 //Qt includes 00009 #include <QDebug> 00010 #include <QIcon> 00011 00013 NeuronGroupModel::NeuronGroupModel() : QAbstractTableModel(){ 00014 connect(Globals::getEventRouter(), SIGNAL(networkChangedSignal()), this, SLOT(loadNeuronGroups())); 00015 connect(Globals::getEventRouter(), SIGNAL(networkDisplayChangedSignal()), this, SLOT(networkDisplayChanged())); 00016 } 00017 00018 00020 NeuronGroupModel::~NeuronGroupModel(){ 00021 } 00022 00023 00024 /*--------------------------------------------------------*/ 00025 /*------- PUBLIC METHODS -------*/ 00026 /*--------------------------------------------------------*/ 00027 00029 void NeuronGroupModel::clearSelection(){ 00030 selectionMap.clear(); 00031 } 00032 00033 00035 int NeuronGroupModel::columnCount(const QModelIndex&) const{ 00036 return NUM_COLS; 00037 } 00038 00039 00042 QVariant NeuronGroupModel::data(const QModelIndex & index, int role) const{ 00043 //Return invalid index if index is invalid or no network loaded 00044 if (!index.isValid()) 00045 return QVariant(); 00046 if(!Globals::networkLoaded()) 00047 return QVariant(); 00048 00049 //Check rows and columns are in range 00050 if (index.row() < 0 || index.row() >= rowCount() || index.column() < 0 || index.column() >= columnCount()) 00051 return QVariant(); 00052 00053 //Return appropriate data 00054 if (role == Qt::DisplayRole){ 00055 if(index.column() == ID_COL) 00056 return neurGrpInfoList[index.row()].getID(); 00057 if(index.column() == NAME_COL) 00058 return neurGrpInfoList[index.row()].getName(); 00059 if(index.column() == DESC_COL) 00060 return neurGrpInfoList[index.row()].getDescription(); 00061 if(index.column() == SIZE_COL) 00062 return neurGrpSizeList[index.row()]; 00063 if(index.column() == NEUR_TYPE_COL) 00064 return neurGrpInfoList[index.row()].getNeuronType().getDescription(); 00065 } 00066 00067 //Icons 00068 if (role == Qt::DecorationRole){ 00069 if(index.column() == VIS_COL ){ 00070 if(Globals::getNetworkDisplay()->neuronGroupVisible(neurGrpInfoList[index.row()].getID())) 00071 return QIcon(Globals::getSpikeStreamRoot() + "/images/visible.xpm"); 00072 return QIcon(Globals::getSpikeStreamRoot() + "/images/hidden.xpm"); 00073 } 00074 if(index.column() == ZOOM_COL){ 00075 unsigned int tmpNeurGrpID = neurGrpInfoList[index.row()].getID(); 00076 NetworkDisplay* netDisplay = Globals::getNetworkDisplay(); 00077 //Zoom enabled on this neuron group 00078 if (netDisplay->isZoomEnabled() && netDisplay->getZoomNeuronGroupID() == tmpNeurGrpID){ 00079 if(netDisplay->getZoomStatus() == NetworkDisplay::ZOOM_SIDE) 00080 return QIcon(Globals::getSpikeStreamRoot() + "/images/zoom_to_highlight.xpm"); 00081 else if(netDisplay->getZoomStatus() == NetworkDisplay::ZOOM_ABOVE) 00082 return QIcon(Globals::getSpikeStreamRoot() + "/images/zoom_above_highlight.xpm"); 00083 } 00084 //Zoom is disabled or enabled on a different neuron group 00085 return QIcon(Globals::getSpikeStreamRoot() + "/images/zoom_to.xpm"); 00086 } 00087 if(index.column() == PARAM_COL){ 00088 return QIcon(Globals::getSpikeStreamRoot() + "/images/parameters.xpm"); 00089 } 00090 } 00091 00092 //Check boxes 00093 if(role == Qt::CheckStateRole){ 00094 if(index.column() == SELECT_COL){ 00095 if(selectionMap.contains(index.row())){ 00096 return true; 00097 } 00098 else { 00099 return false; 00100 } 00101 } 00102 } 00103 00104 //If we have reached this point ignore request 00105 return QVariant(); 00106 } 00107 00108 00111 NeuronGroupInfo NeuronGroupModel::getInfo(const QModelIndex& index) const{ 00112 if(index.row() >= neurGrpInfoList.size()) 00113 throw SpikeStreamException("Index out of range: " + QString::number(index.row())); 00114 return neurGrpInfoList[index.row()]; 00115 } 00116 00117 00119 QHash<QString, double> NeuronGroupModel::getParameters(int row){ 00120 if(row >= rowCount()) 00121 throw SpikeStreamException("Failed to get parameters: row out of range: " + QString::number(row)); 00122 return neurGrpInfoList[row].getParameterMap(); 00123 } 00124 00125 00127 QList<unsigned int> NeuronGroupModel::getSelectedNeuronGroupIDs(){ 00128 //Double check lengths 00129 if(neurGrpInfoList.size() < selectionMap.size()) 00130 throw SpikeStreamException("There are more selected indexes than indexes"); 00131 00132 QList<unsigned int> neurGrpIDList; 00133 foreach(unsigned int index, selectionMap.keys()){ 00134 neurGrpIDList.append(neurGrpInfoList.at(index).getID()); 00135 } 00136 00137 //Return list 00138 return neurGrpIDList; 00139 } 00140 00141 00143 void NeuronGroupModel::reload(){ 00144 loadNeuronGroups(); 00145 } 00146 00147 00149 void NeuronGroupModel::selectAllOrNone(){ 00150 //Deselect all groups 00151 if(selectionMap.size() == neurGrpInfoList.size()){ 00152 selectionMap.clear(); 00153 } 00154 00155 //Select all groups 00156 else{ 00157 for(int i=0; i<neurGrpInfoList.size(); ++i) 00158 selectionMap[i] = true; 00159 } 00160 reset(); 00161 } 00162 00163 00164 00166 void NeuronGroupModel::showAllOrNone(){ 00167 //Make all groups visible if there are none showing 00168 QList<unsigned> visNeurGrpIds = Globals::getNetworkDisplay()->getVisibleNeuronGroupIDs(); 00169 if(visNeurGrpIds.isEmpty()){ 00170 for(int i=0; i<neurGrpInfoList.size(); ++i) 00171 visNeurGrpIds.append(neurGrpInfoList.at(i).getID()); 00172 } 00173 00174 //One or more is hidden: make all groups invisible 00175 else{ 00176 visNeurGrpIds.clear(); 00177 } 00178 Globals::getNetworkDisplay()->setVisibleNeuronGroupIDs(visNeurGrpIds); 00179 reset(); 00180 } 00181 00183 bool NeuronGroupModel::setData(const QModelIndex& index, const QVariant&, int) { 00184 if (!index.isValid() || !Globals::networkLoaded()) 00185 return false; 00186 if (index.row() < 0 || index.row() >= rowCount()) 00187 return false; 00188 00189 //Change visibility of neuron group 00190 if(index.column() == VIS_COL){ 00191 unsigned int tmpNeurGrpID = neurGrpInfoList[index.row()].getID(); 00192 if(Globals::getNetworkDisplay()->neuronGroupVisible(tmpNeurGrpID)) 00193 Globals::getNetworkDisplay()->setNeuronGroupVisibility(tmpNeurGrpID, false); 00194 else 00195 Globals::getNetworkDisplay()->setNeuronGroupVisibility(tmpNeurGrpID, true); 00196 00197 //Emit signal that data has changed and return true to indicate data set succesfully. 00198 emit dataChanged(index, index); 00199 return true; 00200 } 00201 00202 //Change zoom of neuron group 00203 if(index.column() == ZOOM_COL){ 00204 unsigned int tmpNeurGrpID = neurGrpInfoList[index.row()].getID(); 00205 NetworkDisplay* netDisplay = Globals::getNetworkDisplay(); 00206 //We are already zoomed on this neuron 00207 if (netDisplay->isZoomEnabled() && netDisplay->getZoomNeuronGroupID() == tmpNeurGrpID){ 00208 if(netDisplay->getZoomStatus() == NetworkDisplay::ZOOM_SIDE)//We are zoomed into neuron group from the side 00209 netDisplay->setZoom(tmpNeurGrpID, NetworkDisplay::ZOOM_ABOVE);//Zoom neuron group from above 00210 else if(netDisplay->getZoomStatus() == NetworkDisplay::ZOOM_ABOVE)//We are zoomed into neuron group from above 00211 netDisplay->setZoom(0, NetworkDisplay::ZOOM_SIDE);//Zoom whole network from side 00212 } 00213 00214 //Zoom is off or set for another neuron group 00215 else { 00216 netDisplay->setZoom(tmpNeurGrpID, NetworkDisplay::ZOOM_SIDE);//Zoom neuron group from side 00217 } 00218 00219 //Call reset because any of the rows could have changed 00220 reset(); 00221 return true; 00222 } 00223 00224 //Change selection status of neuron group 00225 if(index.column() == SELECT_COL){ 00226 if(selectionMap.contains(index.row())) 00227 selectionMap.remove(index.row()); 00228 else 00229 selectionMap[index.row()] = true; 00230 reset(); 00231 return true; 00232 } 00233 00234 //If we have reached this point no data has been set 00235 return false; 00236 } 00237 00238 00240 QVariant NeuronGroupModel::headerData(int section, Qt::Orientation orientation, int role) const{ 00241 if (role != Qt::DisplayRole) 00242 return QVariant(); 00243 00244 if (orientation == Qt::Horizontal){ 00245 if(section == ID_COL) 00246 return "ID"; 00247 if(section == NAME_COL) 00248 return "Name"; 00249 if(section == DESC_COL) 00250 return "Description"; 00251 if(section == SIZE_COL) 00252 return "Size"; 00253 if(section == NEUR_TYPE_COL) 00254 return "Neuron Type"; 00255 if(section == PARAM_COL) 00256 return "Parameters"; 00257 } 00258 00259 return QVariant(); 00260 00261 } 00262 00263 00265 int NeuronGroupModel::rowCount(const QModelIndex&) const{ 00266 return neurGrpInfoList.size(); 00267 } 00268 00269 00271 void NeuronGroupModel::loadNeuronGroups(){ 00272 //Clear current list of neuron group information 00273 neurGrpInfoList.clear(); 00274 neurGrpSizeList.clear(); 00275 00276 //Get list of current neuron group info 00277 if(Globals::networkLoaded()) 00278 neurGrpInfoList = Globals::getNetwork()->getNeuronGroupsInfo(); 00279 00280 //Load up sizes of connection groups 00281 for(int i=0; i<neurGrpInfoList.size(); ++i) 00282 neurGrpSizeList.append(Globals::getNetwork()->getNeuronGroup(neurGrpInfoList.at(i).getID())->size()); 00283 00284 //Sanity check 00285 if(neurGrpInfoList.size() != neurGrpSizeList.size()) 00286 qCritical()<<"Mismatch between list of neuron group info and list of neuron group size."; 00287 00288 //Instruct listening classes to reload data 00289 this->reset(); 00290 } 00291 00292 00294 void NeuronGroupModel::networkDisplayChanged(){ 00295 reset(); 00296 } 00297 00298