void TimeZoneModel::populateModel()
{
#ifdef HAVE_CITIES
    m_LocationDb = new MLocationDatabase();
#else
    m_LocationDb = new MLocationDatabaseFake();
#endif
    m_Cities = m_LocationDb->cities();
    qSort(m_Cities.begin(), m_Cities.end(), compareCityName);
    QSet<QString> tmz;
    QList<MCity> cityItems;
    
    for(QList<MCity>::iterator iter = m_Cities.begin();
       iter != m_Cities.end(); iter++)
      {
        MCity city = *iter;
    	sm_CityNames[city.key()] = qtTrId(qPrintable(city.key())); 
        sm_CityInCountryNames[city.key()] = qtTrId(qPrintable(city.country().key())); 
        QString key = equalityKey(city);
        if (m_EqualCities.contains(key)) {
            m_EqualCities[key].append(city);
        }
        else //if (!tmz.contains(city.timeZone()))
        {
            tmz.insert(city.timeZone());
	        cityItems.append(city);
            m_LookupByTimeZone[city.timeZone()] = city;
            QChar label = groupLabel(city);
            int groupIndex = m_GroupLabels.indexOf(label);
            if (groupIndex == -1) {
                m_GroupLabels.append(label);
                groupIndex = m_GroupLabels.count() - 1;
            }
             m_GroupMap[groupIndex].append(city);
             QVector<int> indexVec(2);
             indexVec[0] = groupIndex;
             indexVec[1] = m_GroupMap[groupIndex].count() - 1;
             m_TimeZoneIndexMap[city.timeZone()] = indexVec;
             m_EqualCities[key].append(city);
      }
    } 
   for(QList<MCity>::iterator iter = m_Cities.begin();
       iter != m_Cities.end(); iter++)
        {
            MCity city = *iter;
	        cacheCity(city);
        }

}
void LanguageModel::populateModel()
{
    
    DcpDisplayLangConf* conf = DcpDisplayLangConf::instance();
    QStringList availableLangs = conf->availableDisplayLanguages();
    foreach (QString lang, availableLangs)
    {
        LangData data = LangData(lang);
	m_Languages.append(data);
        QChar label = data.name[0];
        int groupIndex = m_GroupLabels.indexOf(label);
        if (groupIndex == -1) {
              m_GroupLabels.append(label);
              groupIndex = m_GroupLabels.count() - 1;
        }
        m_GroupMap[groupIndex].append(data);
        QVector<int> indexVec(2);
        indexVec[0] = groupIndex;
        indexVec[1] = m_GroupMap[groupIndex].count() - 1;
        m_LanguageIndexMap[data.name] = indexVec;
    } 
/**
 * Sort.
 * @param criteria : a vector with a list of pairs: column name, bool;
 *        where bool = true for ascending, false for descending sort.
 */
void TableWorkspace::sort(std::vector<std::pair<std::string, bool>> &criteria) {
  if (criteria.empty())
    return;

  if (criteria.size() > columnCount()) {
    throw std::runtime_error("Too many column names given.");
  }

  const size_t nRows = rowCount();
  if (nRows == 0)
    return;

  // first sort an array of indices according to criteria then put the rows
  // in order of the sorted indices

  std::vector<size_t> indexVec(nRows);
  // initialize the index vector with consecutive numbers
  for (auto i = indexVec.begin() + 1; i != indexVec.end(); ++i) {
    *i = *(i - 1) + 1;
  }

  // dynamically populate and use a queue of records for iteratively sort all
  // rows
  std::queue<SortIterationRecord> sortRecords;
  // start with first pair in criteria and sort all rows
  sortRecords.push(SortIterationRecord(0, 0, nRows));

  // maximum possible number of calls to Column::sortIndex (I think)
  const size_t maxNLoops = criteria.size() * nRows / 2;
  // loop over sortRecords and sort indexVec
  for (size_t counter = 0; counter < maxNLoops; ++counter) {
    // get the record from the front of the queue
    SortIterationRecord record = sortRecords.front();
    sortRecords.pop();
    // define the arguments for Column::sortIndex
    auto &crt = criteria[record.keyIndex];
    const std::string columnName = crt.first;
    const bool ascending = crt.second;
    auto &column = *getColumn(columnName);
    std::vector<std::pair<size_t, size_t>> equalRanges;

    // sort indexVec
    column.sortIndex(ascending, record.iStart, record.iEnd, indexVec,
                     equalRanges);

    // if column had 1 or more ranges of equal values and there is next item in
    // criteria
    // add more records to the back of the queue
    if (record.keyIndex < criteria.size() - 1) {
      size_t keyIndex = record.keyIndex + 1;
      for (auto &equalRange : equalRanges) {
        sortRecords.push(
            SortIterationRecord(keyIndex, equalRange.first, equalRange.second));
      }
    }

    if (sortRecords.empty()) {
      // there is nothing to do
      break;
    }
  }

  // finally sort the rows
  const size_t nCols = columnCount();
  for (size_t i = 0; i < nCols; ++i) {
    getColumn(i)->sortValues(indexVec);
  }
}