// // Updates a document's properties. // void IndexTree::updateDocumentInfo(unsigned int docId, const DocumentInfo &docInfo) { if (docId == 0) { return; } // Go through the list of indexed documents TreeModel::Children children = m_refStore->children(); for (TreeModel::Children::iterator iter = children.begin(); iter != children.end(); ++iter) { TreeModel::Row row = *iter; if (docId == row[m_indexColumns.m_id]) { row[m_indexColumns.m_text] = to_utf8(docInfo.getTitle()); row[m_indexColumns.m_type] = to_utf8(docInfo.getType()); row[m_indexColumns.m_language] = to_utf8(docInfo.getLanguage()); row[m_indexColumns.m_timestamp] = to_utf8(docInfo.getTimestamp()); #ifdef DEBUG cout << "IndexTree::updateDocumentInfo: language now " << docInfo.getLanguage() << endl; #endif break; } } }
// // Deletes the current selection. // bool IndexTree::deleteSelection(void) { bool empty = false; // Go through selected items list<TreeModel::Path> selectedItems = get_selection()->get_selected_rows(); list<TreeModel::Path>::iterator itemPath = selectedItems.begin(); while (itemPath != selectedItems.end()) { TreeModel::iterator iter = m_refStore->get_iter(*itemPath); TreeModel::Row row = *iter; // Unselect and erase get_selection()->unselect(iter); m_refStore->erase(row); selectedItems = get_selection()->get_selected_rows(); itemPath = selectedItems.begin(); } #ifdef DEBUG cout << "IndexTree::deleteSelection: deleted " << selectedItems.size() << " documents" << endl; #endif TreeModel::Children children = m_refStore->children(); if (children.empty() == true) { // The index tree is now empty m_listingIndex = false; empty = true; } return empty; }
void EnginesTree::save(void) { std::map<string, bool> &channels = m_settings.getSearchEnginesChannels(); TreeModel::Children children = m_refStore->children(); for (TreeModel::Children::iterator iter = children.begin(); iter != children.end(); ++iter) { TreeModel::Row row = *iter; if (row[m_enginesColumns.m_type] == EnginesModelColumns::ENGINE_FOLDER) { ustring channelName(row[m_enginesColumns.m_name]); TreeModel::Path channelPath = m_refStore->get_path(iter); std::map<string, bool>::iterator channelIter = channels.find(from_utf8(channelName)); if (channelIter != channels.end()) { #ifdef DEBUG cout << "EnginesTree::save: " << channelName << " is " << row_expanded(channelPath) << endl; #endif channelIter->second = row_expanded(channelPath); } } } }
// // Clears the tree. // void ResultsTree::clear(void) { // Unselect results get_selection()->unselect_all(); // Remove existing rows in the tree TreeModel::Children children = m_refStore->children(); if (children.empty() == false) { // Clear the groups map m_resultsGroups.clear(); TreeModel::Children::iterator iter = children.begin(); while (iter != children.end()) { // Erase this row m_refStore->erase(*iter); // Get the new first row children = m_refStore->children(); iter = children.begin(); } m_refStore->clear(); // Clear the extract field RefPtr<TextBuffer> refBuffer = m_extractTextview->get_buffer(); refBuffer->set_text(""); m_extractTextview->set_editable(false); m_extractTextview->set_cursor_visible(false); onSelectionChanged(); } }
// // Deletes the current selection. // bool ResultsTree::deleteSelection(void) { bool empty = false; // Go through selected items list<TreeModel::Path> selectedItems = get_selection()->get_selected_rows(); list<TreeModel::Path>::iterator itemPath = selectedItems.begin(); while (itemPath != selectedItems.end()) { TreeModel::iterator iter = m_refStore->get_iter(*itemPath); TreeModel::Row row = *iter; TreeModel::iterator parentIter; bool updateParent = false; // This could be a group that's in the map and should be removed first if (row[m_resultsColumns.m_type] != ResultsModelColumns::RESULT_TITLE) { string groupName = from_utf8(row[m_resultsColumns.m_text]); std::map<string, TreeModel::iterator>::iterator mapIter = m_resultsGroups.find(groupName); if (mapIter != m_resultsGroups.end()) { m_resultsGroups.erase(mapIter); #ifdef DEBUG cout << "ResultsTree::deleteResults: erased group " << groupName << endl; #endif } } else { // This item is a result parentIter = row.parent(); updateParent = true; } // Unselect and erase get_selection()->unselect(iter); m_refStore->erase(row); // Update group ? if (updateParent == true) { // Update the group this result belongs to updateGroup(parentIter); } selectedItems = get_selection()->get_selected_rows(); itemPath = selectedItems.begin(); } TreeModel::Children children = m_refStore->children(); empty = children.empty(); refresh(); return empty; }
void WelcomeWindow::PlayerLeftEvent() { CallbackChange *change = m_callbackHandler->PopCallbackChange(); if(change->m_type == CALLBACK_ERROR) { cerr << "ERROR: Got an error in callback processing" << endl; return; } MainLobbyCallbackChange *lobbyChange = (MainLobbyCallbackChange*)change; TreeModel::Children rows = m_playerListStore->children(); TreeModel::iterator rowIter; for(rowIter=rows.begin(); rowIter!=rows.end(); rowIter++) { if(!rowIter) { cerr << "ERROR: A player row was corrupt\n"; continue; } TreeModel::Row row=*rowIter; uint ID = row[m_playerColumns->m_ID]; if(ID == lobbyChange->m_playerID) { m_playerListStore->erase(rowIter); } } for(rowIter=rows.begin(); rowIter!=rows.end(); rowIter++) { TreeModel::Row row=*rowIter; uint ID = row[m_playerColumns->m_ID]; if(ID == lobbyChange->m_newLeaderID ) { row[m_playerColumns->m_isLeader] = true; } else { row[m_playerColumns->m_isLeader] = false; } if(m_playerDescription.m_ID == lobbyChange->m_newLeaderID) { row[m_playerColumns->m_leaderSelectable] = true; swap_leader_widgets(true); } else { row[m_playerColumns->m_leaderSelectable] = false; swap_leader_widgets(false); } } m_currentMatch.m_leaderID = lobbyChange->m_newLeaderID; m_player_list_view->show_all(); }
void WelcomeWindow::TeamChangedEvent() { CallbackChange *change = m_callbackHandler->PopCallbackChange(); if(change->m_type == CALLBACK_ERROR) { cerr << "ERROR: Got an error in callback processing" << endl; return; } MainLobbyCallbackChange *lobbyChange = (MainLobbyCallbackChange*)change; PlayerListColumns playerColumns; TeamComboColumns teamColumns; TreeModel::Children rows = m_playerListStore->children(); TreeModel::iterator rowIter; for(rowIter=rows.begin(); rowIter!=rows.end(); rowIter++) { if(!rowIter) { cerr << "ERROR: A player row was corrupt\n"; continue; } TreeModel::Row playerRow=*rowIter; int ID = playerRow[playerColumns.m_ID]; if( ID == (int)lobbyChange->m_playerID ) { playerRow[playerColumns.m_teamName] = Team::TeamNumberToString((enum TeamNumber)lobbyChange->m_team); // //Get set the new team number back into the combobox's data // TreeValueProxy<Glib::RefPtr<TreeModel> > teamNumberListStore = // playerRow[playerColumns.teamChosen]; // Glib::RefPtr<TreeModel> treeModelPtr = teamNumberListStore; // TreeModel::iterator chosenTeamIter = treeModelPtr->get_iter("0"); // TreeModel::Row existingTeamRow = (*chosenTeamIter); // existingTeamRow[teamColumns.teamNum] = change.team; // existingTeamRow[teamColumns.teamString] = // Team::TeamNumberToString((enum TeamNumber)change.team); m_player_list_view->show_all(); break; } } }
// // Clear the tree. // void EnginesTree::clear(void) { // Unselect engines get_selection()->unselect_all(); // Remove existing rows in the tree TreeModel::Children children = m_refStore->children(); if (children.empty() == false) { TreeModel::Children::iterator iter = children.begin(); while (iter != children.end()) { // Erase this row m_refStore->erase(*iter); // Get the new first row children = m_refStore->children(); iter = children.begin(); } m_refStore->clear(); } }
// // Updates a results group. // void ResultsTree::updateGroup(TreeModel::iterator &groupIter) { TreeModel::Row groupRow = (*groupIter); // Check the iterator doesn't point to a result if (groupRow[m_resultsColumns.m_type] == ResultsModelColumns::RESULT_TITLE) { return; } // Modify the "score" column to indicate the number of results in that group TreeModel::Children groupChildren = groupIter->children(); char scoreStr[64]; snprintf(scoreStr, 64, "%u", groupChildren.size()); groupRow[m_resultsColumns.m_score] = scoreStr; #ifdef DEBUG cout << "ResultsTree::updateGroup: group " << groupRow[m_resultsColumns.m_text] << " has " << groupChildren.size() << " children" << endl; #endif // Expand this group TreeModel::Path groupPath = m_refStore->get_path(groupIter); expand_row(groupPath, true); }
Gtk::TreeModel::iterator TaskList::subSearch(int id, TreeModel::Children children) { TreeIter iter; for (iter = children.begin(); iter != children.end(); iter++) { TreeModel::Row row = *iter; if (row.children().size() > 0) { TreeIter subIter = subSearch(id, row.children()); if (subIter != row.children().end()) { iter = subIter; break; } } if (row[columns.col_id] == id) { break; } } return iter; }
void WelcomeWindow::on_leader_toggled(const Glib::ustring& path) { PlayerListColumns playerColumns; Glib::RefPtr<TreeModel> playerModelPtr = m_playerListStore; TreeModel::iterator chosenPlayerIter = playerModelPtr->get_iter(path); if(!chosenPlayerIter) { cerr << "ERROR: Invalid player row selected for changing leader\n"; m_match_lobby_status->push("Could not change the leader"); m_player_list_view->show_all(); return; } TreeModel::Row chosenPlayerRow = (*chosenPlayerIter); uint newLeaderID = chosenPlayerRow[playerColumns.m_ID]; if(ChangeLeader(newLeaderID) == false) { cerr << "WARNING: Change of leader on the server failed\n"; m_match_lobby_status->push("Could not change the leader"); m_player_list_view->show_all(); return; } TreeModel::Children rows = m_playerListStore->children(); TreeModel::iterator r; for(r=rows.begin(); r!=rows.end(); r++) { TreeModel::Row row=*r; row[playerColumns.m_isLeader] = false; row[playerColumns.m_leaderSelectable] = false; } chosenPlayerRow[playerColumns.m_isLeader] = true; m_currentMatch.m_leaderID = newLeaderID; m_player_list_view->show_all(); }
// // Updates a results group. // void ResultsTree::updateGroup(TreeModel::iterator &groupIter) { TreeModel::Row groupRow = (*groupIter); int averageScore = 0; // Check the iterator doesn't point to a result if (groupRow[m_resultsColumns.m_type] == ResultsModelColumns::RESULT_TITLE) { return; } // Modify the "score" column to indicate the number of results in that group TreeModel::Children groupChildren = groupIter->children(); if (groupChildren.empty() == false) { for (TreeModel::Children::iterator childIter = groupChildren.begin(); childIter != groupChildren.end(); ++childIter) { TreeModel::Row row = *childIter; averageScore += row[m_resultsColumns.m_score]; } averageScore = (int)(averageScore / groupChildren.size()); } groupRow[m_resultsColumns.m_score] = averageScore; #ifdef DEBUG cout << "ResultsTree::updateGroup: group " << groupRow[m_resultsColumns.m_text] << " has score " << averageScore << endl; #endif // Expand this group TreeModel::Path groupPath = m_refStore->get_path(groupIter); expand_row(groupPath, true); }
// // Sets how results are grouped. // void ResultsTree::setGroupMode(bool groupBySearchEngine) { ResultsModelColumns::ResultType currentType, newType; if (m_groupBySearchEngine == groupBySearchEngine) { // No change return; } m_groupBySearchEngine = groupBySearchEngine; // Do we need to update the tree ? TreeModel::Children children = m_refStore->children(); if (children.empty() == true) { return; } // What's the new grouping criteria ? if (groupBySearchEngine == true) { // By search engine currentType = ResultsModelColumns::RESULT_HOST; newType = ResultsModelColumns::RESULT_ROOT; } else { // By host currentType = ResultsModelColumns::RESULT_ROOT; newType = ResultsModelColumns::RESULT_HOST; } // Clear the map m_resultsGroups.clear(); // Unselect results get_selection()->unselect_all(); TreeModel::Children::iterator iter = children.begin(); while (iter != children.end()) { TreeModel::Row row = *iter; #ifdef DEBUG cout << "ResultsTree::groupBySearchEngine: looking at " << row[m_resultsColumns.m_text] << endl; #endif ResultsModelColumns::ResultType type = row[m_resultsColumns.m_type]; // Skip new type rows if (type == newType) { iter++; continue; } TreeModel::Children child = iter->children(); if (child.empty() == false) { TreeModel::Children::iterator childIter = child.begin(); // Type RESULT_TITLE while (childIter != child.end()) { TreeModel::Row childRow = *childIter; TreeModel::iterator groupIter, newIter; bool success = false; // We will need the URL and engines columns in all cases string url = from_utf8(childRow[m_resultsColumns.m_url]); unsigned int engineIds = childRow[m_resultsColumns.m_engines]; unsigned int indexIds = childRow[m_resultsColumns.m_indexes]; // Get the name of the group this should go into if (newType == ResultsModelColumns::RESULT_HOST) { Url urlObj(url); #ifdef DEBUG cout << "ResultsTree::groupBySearchEngine: row " << url << endl; #endif string groupName = urlObj.getHost(); // Add group if (appendGroup(groupName, newType, groupIter) == true) { // Add result success = appendResult(childRow[m_resultsColumns.m_text], childRow[m_resultsColumns.m_url], (float)atof(from_utf8(childRow[m_resultsColumns.m_score]).c_str()), from_utf8(childRow[m_resultsColumns.m_language]), childRow[m_resultsColumns.m_rankDiff], from_utf8(childRow[m_resultsColumns.m_queryName]), engineIds, indexIds, newIter, &(*groupIter), true); } } else { // Look at the engines column and see which engines this result is for set<string> engineNames; m_settings.getEngineNames(engineIds, engineNames); if (engineNames.empty() == false) { #ifdef DEBUG cout << "ResultsTree::groupBySearchEngine: row is for " << engineNames.size() << endl; #endif // Are there indexes in the list ? set<string>::iterator xapianIter = engineNames.find("Xapian"); if ((xapianIter != engineNames.end()) && (indexIds > 0)) { // Erase this engineNames.erase(xapianIter); // Add entries for each index name so that we can loop once on engine names set<string> indexNames; m_settings.getIndexNames(indexIds, indexNames); for (set<string>::iterator iter = indexNames.begin(); iter != indexNames.end(); ++iter) { string indexName = (*iter); engineNames.insert(indexName); #ifdef DEBUG cout << "ResultsTree::groupBySearchEngine: row is for index " << indexName << endl; #endif } } for (set<string>::iterator iter = engineNames.begin(); iter != engineNames.end(); ++iter) { string engineName = (*iter); unsigned int indexId = 0; unsigned int engineId = m_settings.getEngineId(engineName); if (engineId == 0) { // This is actually an index, not an engine... indexId = m_settings.getIndexId(engineName); if (indexId > 0) { engineId = m_settings.getEngineId("Xapian"); } } // Add group if (appendGroup(engineName, newType, groupIter) == true) { // Add result appendResult(childRow[m_resultsColumns.m_text], childRow[m_resultsColumns.m_url], (float)atof(from_utf8(childRow[m_resultsColumns.m_score]).c_str()), from_utf8(childRow[m_resultsColumns.m_language]), childRow[m_resultsColumns.m_rankDiff], from_utf8(childRow[m_resultsColumns.m_queryName]), engineId, indexId, newIter, &(*groupIter), true); #ifdef DEBUG cout << "ResultsTree::groupBySearchEngine: row for " << *iter << endl; #endif } } // FIXME: make sure at least one row was added success = true; } } if (success == true) { // Delete it m_refStore->erase(*childIter); childIter = child.begin(); } else { // Don't delete anything then, just go to the next child childIter++; } } } // Erase this row m_refStore->erase(*iter); // Get the new first row, that way we don't have to worry about iterators validity iter = children.begin(); } for (std::map<string, TreeModel::iterator>::iterator mapIter = m_resultsGroups.begin(); mapIter != m_resultsGroups.end(); mapIter++) { TreeModel::iterator groupIter = mapIter->second; updateGroup(groupIter); } onSelectionChanged(); }
// // Adds a new row in the results tree. // bool ResultsTree::appendResult(const ustring &text, const ustring &url, float score, const string &language, int rankDiff, const string &queryName, unsigned int engineId, unsigned int indexId, TreeModel::iterator &newRowIter, const TreeModel::Row *parentRow, bool noDuplicates) { if (parentRow == NULL) { newRowIter = m_refStore->append(); } else { // Merge duplicates within groups ? if (noDuplicates == true) { // Look for a row with the same URL and query. For instance, in group // by host mode, if a page is returned by several search engines, it // should appear only once TreeModel::Children children = parentRow->children(); if (children.empty() == false) { TreeModel::Children::iterator childIter = children.begin(); for (; childIter != children.end(); ++childIter) { TreeModel::Row row = *childIter; if ((row[m_resultsColumns.m_url] == to_utf8(url)) && (row[m_resultsColumns.m_queryName] == to_utf8(queryName))) { // Update the engines column... row[m_resultsColumns.m_engines] = row[m_resultsColumns.m_engines] | engineId; // ...and the indexes column too row[m_resultsColumns.m_indexes] = row[m_resultsColumns.m_indexes] | engineId; #ifdef DEBUG cout << "ResultsTree::appendResult: merged " << text << " " << engineId << " (" << row[m_resultsColumns.m_engines] << "," << row[m_resultsColumns.m_indexes] << ")" << endl; #endif newRowIter = childIter; return true; } } } } newRowIter = m_refStore->append(parentRow->children()); #ifdef DEBUG cout << "ResultsTree::appendResult: added " << text << ", " << score << " to " << (*parentRow)[m_resultsColumns.m_text] << endl; #endif } XapianIndex index(m_settings.m_indexLocation); ViewHistory viewHistory(m_settings.m_historyDatabase); bool isIndexed = false; // Is this document indexed ? if ((index.isGood() == true) && (index.hasDocument(url) > 0)) { isIndexed = true; } // Has it been already viewed ? bool wasViewed = viewHistory.hasItem(url); char scoreStr[128]; snprintf(scoreStr, 128, "%.f", score); TreeModel::Row childRow = *newRowIter; updateRow(childRow, text, url, scoreStr, to_utf8(language), to_utf8(queryName), engineId, indexId, ResultsModelColumns::RESULT_TITLE, isIndexed, wasViewed, rankDiff); return true; }
// // Deletes results. // bool ResultsTree::deleteResults(QueryProperties &queryProps, const string &engineName) { ustring queryName(queryProps.getName()); unsigned int indexId = 0; unsigned int engineId = m_settings.getEngineId(engineName); unsigned int count = 0; if (engineId == 0) { // Chances are this engine is an index std::map<string, string>::const_iterator mapIter = m_settings.getIndexes().find(engineName); if (mapIter != m_settings.getIndexes().end()) { // Yes, it is indexId = m_settings.getIndexId(engineName); engineId = m_settings.getEngineId("Xapian"); } } TreeModel::Children groups = m_refStore->children(); for (TreeModel::Children::iterator parentIter = groups.begin(); parentIter != groups.end(); ++parentIter) { TreeModel::Row row = *parentIter; if ((row[m_resultsColumns.m_type] != ResultsModelColumns::RESULT_ROOT) && (row[m_resultsColumns.m_type] != ResultsModelColumns::RESULT_HOST)) { continue; } TreeModel::Children children = parentIter->children(); TreeModel::Children::iterator iter = children.begin(); while (iter != children.end()) { row = *iter; if ((row[m_resultsColumns.m_type] == ResultsModelColumns::RESULT_TITLE) && (row[m_resultsColumns.m_engines] == engineId) && (row[m_resultsColumns.m_indexes] == indexId)) { TreeModel::Children::iterator nextIter = iter; ++nextIter; ++count; // Erase this row m_refStore->erase(*iter); iter = nextIter; continue; } // Next ++iter; } } if (count > 0) { onSelectionChanged(); #ifdef DEBUG cout << "ResultsTree::deleteResults: erased " << count << " rows" << endl; #endif return true; } return false; }