void DvbEpgChannelTableModel::setManager(DvbManager *manager) { DvbEpgModel *epgModel = manager->getEpgModel(); connect(epgModel, SIGNAL(epgChannelAdded(DvbSharedChannel)), this, SLOT(epgChannelAdded(DvbSharedChannel))); connect(epgModel, SIGNAL(epgChannelRemoved(DvbSharedChannel)), this, SLOT(epgChannelRemoved(DvbSharedChannel))); // theoretically we should monitor the channel model for updated channels, // but it's very unlikely that this has practical relevance QHeaderView *headerView = manager->getChannelView()->header(); DvbChannelLessThan::SortOrder sortOrder; if (headerView->sortIndicatorOrder() == Qt::AscendingOrder) { if (headerView->sortIndicatorSection() == 0) { sortOrder = DvbChannelLessThan::ChannelNameAscending; } else { sortOrder = DvbChannelLessThan::ChannelNumberAscending; } } else { if (headerView->sortIndicatorSection() == 0) { sortOrder = DvbChannelLessThan::ChannelNameDescending; } else { sortOrder = DvbChannelLessThan::ChannelNumberDescending; } } internalSort(sortOrder); resetFromKeys(epgModel->getEpgChannels()); }
static size_t internalSort ( std::vector<int>& data ) { if ( data.size() == 1 ) return 1; std::vector<int> left ( data.begin(), data.begin() + data.size() / 2 ); std::vector<int> right ( data.begin() + data.size() / 2, data.end() ); size_t ret = internalSort ( left ); ret += internalSort ( right ); size_t li = 0; size_t ri = 0; std::vector<int> output; while ( li < left.size() && ri < right.size() ) { if ( left.at ( li ) < right.at ( ri ) ) { output.push_back ( left.at ( li ) ); ++li; } else { output.push_back ( right.at ( ri ) ); ++ri; } } for ( ; li < left.size(); ++li ) output.push_back ( left.at ( li ) ); for ( ; ri < right.size(); ++ri ) output.push_back ( right.at ( ri ) ); data = output; return ret; }
void DvbChannelTableModel::sort(int column, Qt::SortOrder order) { DvbChannelLessThan::SortOrder sortOrder; if (order == Qt::AscendingOrder) { if (column == 0) { sortOrder = DvbChannelLessThan::ChannelNameAscending; } else { sortOrder = DvbChannelLessThan::ChannelNumberAscending; } } else { if (column == 0) { sortOrder = DvbChannelLessThan::ChannelNameDescending; } else { sortOrder = DvbChannelLessThan::ChannelNumberDescending; } } internalSort(sortOrder); }
static size_t sort ( std::vector<int>& data ) { return internalSort ( data ); }
bool ModList::update() { if (!isValid()) return false; QList<Mod> orderedMods; QList<Mod> newMods; m_dir.refresh(); auto folderContents = m_dir.entryInfoList(); bool orderOrStateChanged = false; // first, process the ordered items (if any) OrderList listOrder = readListFile(); for (auto item : listOrder) { QFileInfo infoEnabled(m_dir.filePath(item.id)); QFileInfo infoDisabled(m_dir.filePath(item.id + ".disabled")); int idxEnabled = folderContents.indexOf(infoEnabled); int idxDisabled = folderContents.indexOf(infoDisabled); bool isEnabled; // if both enabled and disabled versions are present, it's a special case... if (idxEnabled >= 0 && idxDisabled >= 0) { // we only process the one we actually have in the order file. // and exactly as we have it. // THIS IS A CORNER CASE isEnabled = item.enabled; } else { // only one is present. // we pick the one that we found. // we assume the mod was enabled/disabled by external means isEnabled = idxEnabled >= 0; } int idx = isEnabled ? idxEnabled : idxDisabled; QFileInfo &info = isEnabled ? infoEnabled : infoDisabled; // if the file from the index file exists if (idx != -1) { // remove from the actual folder contents list folderContents.takeAt(idx); // append the new mod orderedMods.append(Mod(info)); if (isEnabled != item.enabled) orderOrStateChanged = true; } else { orderOrStateChanged = true; } } // if there are any untracked files... if (folderContents.size()) { // the order surely changed! for (auto entry : folderContents) { newMods.append(Mod(entry)); } internalSort(newMods); orderedMods.append(newMods); orderOrStateChanged = true; } // otherwise, if we were already tracking some mods else if (mods.size()) { // if the number doesn't match, order changed. if (mods.size() != orderedMods.size()) orderOrStateChanged = true; // if it does match, compare the mods themselves else for (int i = 0; i < mods.size(); i++) { if (!mods[i].strongCompare(orderedMods[i])) { orderOrStateChanged = true; break; } } } beginResetModel(); mods.swap(orderedMods); endResetModel(); if (orderOrStateChanged && !m_list_file.isEmpty()) { QLOG_INFO() << "Mod list " << m_list_file << " changed!"; saveListFile(); emit changed(); } return true; }
bool ModList::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) { if (action == Qt::IgnoreAction) return true; // check if the action is supported if (!data || !(action & supportedDropActions())) return false; if (parent.isValid()) { row = parent.row(); column = parent.column(); } if (row > rowCount()) row = rowCount(); if (row == -1) row = rowCount(); if (column == -1) column = 0; QLOG_INFO() << "Drop row: " << row << " column: " << column; // files dropped from outside? if (data->hasUrls()) { bool was_watching = is_watching; if (was_watching) stopWatching(); auto urls = data->urls(); for (auto url : urls) { // only local files may be dropped... if (!url.isLocalFile()) continue; QString filename = url.toLocalFile(); installMod(filename, row); QLOG_INFO() << "installing: " << filename; // if there is no ordering, re-sort the list if (m_list_file.isEmpty()) { beginResetModel(); internalSort(mods); endResetModel(); } } if (was_watching) startWatching(); return true; } else if (data->hasText()) { QString sourcestr = data->text(); auto list = sourcestr.split('|'); if (list.size() != 2) return false; QString remoteId = list[0]; int remoteIndex = list[1].toInt(); QLOG_INFO() << "move: " << sourcestr; // no moving of things between two lists if (remoteId != m_list_id) return false; // no point moving to the same place... if (row == remoteIndex) return false; // otherwise, move the mod :D moveModTo(remoteIndex, row); return true; } return false; }