const QIcon Flags::getIconWithText(const LayoutUnit& layoutUnit, const KeyboardConfig& keyboardConfig) { QString keySuffix(getPixmapKey(keyboardConfig)); QString key(layoutUnit.toString() + keySuffix); if( iconOrTextMap.contains(key) ) { return iconOrTextMap[ key ]; } if( keyboardConfig.indicatorType == KeyboardConfig::SHOW_FLAG ) { QIcon icon = getIcon(layoutUnit.layout); if( ! icon.isNull() ) { iconOrTextMap[ key ] = icon; return icon; } } QString layoutText = Flags::getShortText(layoutUnit, keyboardConfig); const QSize TRAY_ICON_SIZE(21, 14); QPixmap pixmap = QPixmap(TRAY_ICON_SIZE); pixmap.fill(Qt::transparent); QPainter painter(&pixmap); // p.setRenderHint(QPainter::SmoothPixmapTransform); // p.setRenderHint(QPainter::Antialiasing); if( keyboardConfig.indicatorType == KeyboardConfig::SHOW_LABEL_ON_FLAG ) { QIcon iconf = createIcon(layoutUnit.layout); iconf.paint(&painter, painter.window(), Qt::AlignCenter); } drawLabel(painter, layoutText, keyboardConfig.isFlagShown()); painter.end(); QIcon icon(pixmap); iconOrTextMap[ key ] = icon; return icon; }
/*! \brief Create header of netcdf file There are some information to fill in header of each netcdf. */ void CFile::createHeader(void) { CContext* context = CContext::getCurrent(); CContextServer* server = context->server; if (!allDomainEmpty) { StdString filename = getFileOutputName(); // determine splitting format in the file name : firstPart%start_date%middlePart%end_date%lastPart std::string strStartDate="%start_date%" ; std::string strEndDate="%end_date%" ; std::string firstPart ; std::string middlePart ; std::string lastPart ; size_t pos1, pos2 ; bool hasStartDate=false ; bool hasEndDate=false ; bool hasSplit = (!split_freq.isEmpty()); pos1=filename.find(strStartDate) ; if (pos1!=std::string::npos) { firstPart=filename.substr(0,pos1) ; pos1+=strStartDate.size() ; hasStartDate=true ; } else pos1=0 ; pos2=filename.find(strEndDate,pos1) ; if (pos2!=std::string::npos) { middlePart=filename.substr(pos1,pos2-pos1) ; pos2+=strEndDate.size() ; lastPart=filename.substr(pos2,filename.size()-pos2) ; hasEndDate=true ; } else middlePart=filename.substr(pos1,filename.size()) ; if (!hasStartDate && !hasEndDate) { hasStartDate=true ; hasEndDate=true; firstPart=middlePart ; if (hasSplit) firstPart +="_"; middlePart="-" ; } StdOStringStream oss; if (!split_freq.isEmpty()) { CDate split_start ; CDate splitEnd ; if (!split_start_offset.isEmpty()) split_start=lastSplit + split_start_offset ; else split_start=lastSplit ; splitEnd = lastSplit + split_freq ; if (!split_last_date.isEmpty()) { CDate splitLastDate=CDate::FromString(split_last_date,*CContext::getCurrent()->getCalendar()) ; if( splitLastDate < splitEnd) splitEnd=splitLastDate ; } if (!split_end_offset.isEmpty()) splitEnd = splitEnd + split_end_offset; else splitEnd = splitEnd - 1 * Second; string splitFormat; if (split_freq_format.isEmpty()) { if (split_freq.getValue().second != 0) splitFormat = "%y%mo%d%h%mi%s"; else if (split_freq.getValue().minute != 0) splitFormat = "%y%mo%d%h%mi"; else if (split_freq.getValue().hour != 0) splitFormat = "%y%mo%d%h"; else if (split_freq.getValue().day != 0) splitFormat = "%y%mo%d"; else if (split_freq.getValue().month != 0) splitFormat = "%y%mo"; else splitFormat = "%y"; } else splitFormat = split_freq_format; oss << firstPart ; if (hasStartDate) oss << split_start.getStr(splitFormat) ; oss << middlePart ; if (hasEndDate) oss << splitEnd.getStr(splitFormat); oss << lastPart ; StdString keySuffix("CContext_"+CContext::getCurrent()->getId()+"::CFile_"+getFileOutputName()+"::") ; context->registryOut->setKey(keySuffix+"splitStart", lastSplit); context->registryOut->setKey(keySuffix+"splitEnd", splitEnd); } else oss<<firstPart<<lastPart ; bool append = !this->append.isEmpty() && this->append.getValue(); bool useClassicFormat = !format.isEmpty() && format == format_attr::netcdf4_classic; bool useCFConvention = convention.isEmpty() || convention == convention_attr::CF; bool multifile = true; if (!type.isEmpty()) { if (type == type_attr::one_file) multifile = false; else if (type == type_attr::multiple_file) multifile = true; } #ifndef USING_NETCDF_PAR if (!multifile) { info(0) << "!!! Warning -> Using non parallel version of netcdf, switching in multiple_file mode for file : " << filename << " ..." << endl; multifile = true; } #endif if (multifile) { int commSize, commRank; MPI_Comm_size(fileComm, &commSize); MPI_Comm_rank(fileComm, &commRank); if (server->intraCommSize > 1) { oss << "_" ; int width=0; int n = commSize-1; while (n != 0) { n = n / 10; width++;} if (!min_digits.isEmpty()) if (width < min_digits) width = min_digits; oss.width(width); oss.fill('0'); oss << right << commRank; } } oss << ".nc"; bool isCollective = par_access.isEmpty() || par_access == par_access_attr::collective; if (isOpen) data_out->closeFile(); data_out = shared_ptr<CDataOutput>(new CNc4DataOutput(this, oss.str(), append, useClassicFormat, useCFConvention, fileComm, multifile, isCollective, time_counter_name)); isOpen = true; data_out->writeFile(CFile::get(this)); // Do not recreate the file structure if opening an existing file if (!data_out->IsInAppendMode()) { std::vector<CField*>::iterator it, end = this->enabledFields.end(); for (it = this->enabledFields.begin(); it != end; it++) { CField* field = *it; this->data_out->writeFieldGrid(field); } this->data_out->writeTimeDimension(); for (it = this->enabledFields.begin(); it != end; it++) { CField* field = *it; this->data_out->writeFieldTimeAxis(field); } for (it = this->enabledFields.begin(); it != end; it++) { CField* field = *it; this->data_out->writeField(field); } vector<CVariable*> listVars = getAllVariables(); for (vector<CVariable*>::iterator it = listVars.begin(); it != listVars.end(); it++) this->data_out->writeAttribute(*it); this->data_out->definition_end(); } else { // check time axis even in append mode std::vector<CField*>::iterator it, end = this->enabledFields.end(); for (it = this->enabledFields.begin(); it != end; it++) { CField* field = *it; this->data_out->writeFieldTimeAxis(field); } } } }
//! Initialize a file in order to write into it void CFile::initFile(void) { CContext* context = CContext::getCurrent(); const CDate& currentDate = context->calendar->getCurrentDate(); CContextServer* server = context->server; lastSync = currentDate; lastSplit = currentDate; if (!split_freq.isEmpty()) { StdString keySuffix("CContext_"+CContext::getCurrent()->getId()+"::CFile_"+getFileOutputName()+"::") ; if (context->registryIn->foundKey(keySuffix+"splitStart") && context->registryIn->foundKey(keySuffix+"splitEnd")) { CDate savedSplitStart(*context->getCalendar()), savedSplitEnd(*context->getCalendar()); context->registryIn->getKey(keySuffix+"splitStart", savedSplitStart); context->registryIn->getKey(keySuffix+"splitEnd", savedSplitEnd); if (savedSplitStart <= lastSplit && lastSplit <= savedSplitEnd) lastSplit = savedSplitStart; } } isOpen = false; allDomainEmpty = true; // if (!record_offset.isEmpty() && record_offset < 0) // ERROR("void CFile::initFile(void)", // "Invalid 'record_offset', this attribute cannot be negative."); const int recordOffset = record_offset.isEmpty() ? 0 : record_offset; // set<CAxis*> setAxis; // set<CDomain*> setDomains; set<StdString> setAxis; set<StdString> setDomains; std::vector<CField*>::iterator it, end = this->enabledFields.end(); for (it = this->enabledFields.begin(); it != end; it++) { CField* field = *it; allDomainEmpty &= !field->grid->doGridHaveDataToWrite(); std::vector<CAxis*> vecAxis = field->grid->getAxis(); for (size_t i = 0; i < vecAxis.size(); ++i) setAxis.insert(vecAxis[i]->getAxisOutputName()); // setAxis.insert(vecAxis[i]); std::vector<CDomain*> vecDomains = field->grid->getDomains(); for (size_t i = 0; i < vecDomains.size(); ++i) setDomains.insert(vecDomains[i]->getDomainOutputName()); // setDomains.insert(vecDomains[i]); field->resetNStep(recordOffset); } nbAxis = setAxis.size(); nbDomains = setDomains.size(); // create sub communicator for file int color = allDomainEmpty ? 0 : 1; MPI_Comm_split(server->intraComm, color, server->intraCommRank, &fileComm); if (allDomainEmpty) MPI_Comm_free(&fileComm); // if (time_counter.isEmpty()) time_counter.setValue(time_counter_attr::centered); if (time_counter_name.isEmpty()) time_counter_name = "time_counter"; }