void Cashbox::updateTotals() { QString text;// = "<h1>Свод по кассе</h1><br>"; QSqlQuery query; double summOnStart = 0; QDate start_date = QDate(2000,1,1); QTime start_time = QTime(0,0,0); QSettings *settings = data->getSettings(); query.prepare(settings->value("cashbox/queries/first_shiftwork_document").toString()); query.bindValue(":store", data->getVariables()->value("current_base_id")); query.bindValue(":user", data->getVariables()->value("user_id")); if(!query.exec()){ qDebug()<<posInFile<<query.lastError().text()<<endl<<query.lastQuery()<<endl<<query.boundValues(); }else { if(query.next()){ start_date = query.value(0).toDate(); start_time = query.value(1).toTime(); } } text += "<h2>Товарные операции</h2>"; query.prepare(settings->value("cashbox/queries/goods_operations_sum").toString()); query.bindValue(":time_start",start_time); query.bindValue(":date_start",start_date); query.bindValue(":date_start2",start_date); if(!query.exec()){ qDebug()<<posInFile<<query.lastError().text()<<endl<<query.lastQuery()<<endl<<query.boundValues(); } while (query.next()) { text += "<li>"+query.value(0).toString() + ": "+ QString::number(query.value(1).toDouble(),'f',2); summOnStart -= query.value(1).toDouble(); } text += "<h2>Денежные операции</h2>"; query.prepare(settings->value("cashbox/queries/money_operations_sum").toString()); query.bindValue(":time_start",start_time); query.bindValue(":date_start",start_date); query.bindValue(":date_start2",start_date); // qDebug()<<query.lastQuery()<<Service::join(query.boundValues()); if(!query.exec()){ qDebug()<<posInFile<<query.lastError().text()<<endl<<query.lastQuery()<<endl<<query.boundValues(); } while (query.next()) { text += "<li>"+query.value(0).toString() + ": "+ QString::number(query.value(1).toDouble(),'f',2); summOnStart -= query.value(1).toDouble(); } query.prepare(settings->value("cashbox/queries/rests_goods_sum").toString()); if(!query.exec()){ qDebug()<<posInFile<<query.lastError().text()<<endl<<query.lastQuery()<<endl<<query.boundValues(); } double rests = 0; while (query.next()) rests += query.value(0).toDouble(); query.prepare(settings->value("cashbox/queries/rests_money_sum").toString()); if(!query.exec()){ qDebug()<<posInFile<<query.lastError().text()<<endl<<query.lastQuery()<<endl<<query.boundValues(); } while (query.next()) rests += query.value(0).toDouble(); text += "<h2>Остаток в кассе: "+ QString::number(rests,'f',2)+"</h2>"; summOnStart += rests; text = "Смена с "+start_date.toString("dd.MM.yyyy")+" "+start_time.toString("hh:mm:ss") + "<h2>Остаток на начало: "+ QString::number(summOnStart,'f',2)+"</h2>" + text; totals.setText(text); }
bool ManualSchedule::Create(void) { if (!LoadWindowFromXML("schedule-ui.xml", "manualschedule", this)) return false; m_channelList = dynamic_cast<MythUIButtonList *>(GetChild("channel")); m_startdateList = dynamic_cast<MythUIButtonList *>(GetChild("startdate")); m_starthourSpin = dynamic_cast<MythUISpinBox *>(GetChild("starthour")); m_startminuteSpin = dynamic_cast<MythUISpinBox *>(GetChild("startminute")); m_durationSpin = dynamic_cast<MythUISpinBox *>(GetChild("duration")); m_titleEdit = dynamic_cast<MythUITextEdit *>(GetChild("title")); m_recordButton = dynamic_cast<MythUIButton *>(GetChild("next")); m_cancelButton = dynamic_cast<MythUIButton *>(GetChild("cancel")); if (!m_channelList || !m_startdateList || !m_starthourSpin || !m_startminuteSpin || !m_durationSpin || !m_titleEdit || !m_recordButton || !m_cancelButton) { VERBOSE(VB_IMPORTANT, "ManualSchedule, theme is missing " "required elements"); return false; } QString longChannelFormat = gCoreContext->GetSetting("LongChannelFormat", "<num> <name>"); QString chanorder = gCoreContext->GetSetting("ChannelOrdering", "channum"); DBChanList channels = ChannelUtil::GetChannels(0, false, "channum,callsign"); ChannelUtil::SortChannels(channels, chanorder); for (uint i = 0; i < channels.size(); i++) { QString chantext = longChannelFormat; chantext .replace("<num>", channels[i].channum) .replace("<sign>", channels[i].callsign) .replace("<name>", channels[i].name); chantext.detach(); new MythUIButtonListItem(m_channelList, chantext); m_chanids.push_back(channels[i].chanid); } for (uint index = 0; index <= 60; index++) { QString dinfo = m_nowDateTime.addDays(index).toString(m_dateformat); if (m_nowDateTime.addDays(index).date().dayOfWeek() < 6) dinfo += QString(" (%1)").arg(tr("5 weekdays if daily")); else dinfo += QString(" (%1)").arg(tr("7 days per week if daily")); new MythUIButtonListItem(m_startdateList, dinfo); if (m_nowDateTime.addDays(index).toString("MMdd") == m_startDateTime.toString("MMdd")) m_startdateList->SetItemCurrent(m_startdateList->GetCount() - 1); } QTime thisTime = m_nowDateTime.time(); thisTime = thisTime.addSecs((30 - (thisTime.minute() % 30)) * 60); if (thisTime < QTime(0,30)) m_startdateList->SetItemCurrent(m_startdateList->GetCurrentPos() + 1); m_starthourSpin->SetRange(0,23,1); m_starthourSpin->SetValue(thisTime.hour()); int minute_increment = gCoreContext->GetNumSetting("ManualScheduleMinuteIncrement", 5); m_startminuteSpin->SetRange(0, 60-minute_increment, minute_increment); m_startminuteSpin->SetValue((thisTime.minute()/5)*5); m_durationSpin->SetRange(5,360,5); m_durationSpin->SetValue(60); connectSignals(); connect(m_recordButton, SIGNAL(Clicked()), SLOT(recordClicked())); connect(m_cancelButton, SIGNAL(Clicked()), SLOT(Close())); m_titleEdit->SetMaxLength(128); BuildFocusList(); return true; }
UI_AveragerWindow::UI_AveragerWindow(QWidget *w_parent, int annot_nr) { int i, n; long long recording_duration; struct annotationblock *annot; mainwindow = (UI_Mainwindow *)w_parent; averager_dialog = new QDialog(w_parent); averager_dialog->setMinimumSize(600, 400); averager_dialog->setMaximumSize(600, 400); averager_dialog->setWindowTitle("Average waveforms"); averager_dialog->setModal(true); averager_dialog->setAttribute(Qt::WA_DeleteOnClose, true); annotLabel = new QLabel(averager_dialog); annotLabel->setGeometry(20, 20, 100, 25); annotLabel->setText("Use annotation:"); annotNameLabel = new QLabel(averager_dialog); annotNameLabel->setGeometry(130, 20, 200, 25); signalLabel = new QLabel(averager_dialog); signalLabel->setGeometry(340, 20, 100, 25); signalLabel->setText("Select signal(s):"); list = new QListWidget(averager_dialog); list->setGeometry(450, 20, 130, 360); list->setSelectionBehavior(QAbstractItemView::SelectRows); list->setSelectionMode(QAbstractItemView::ExtendedSelection); time1.setHMS(0, 0, 0, 0); recording_duration = (mainwindow->edfheaderlist[0]->datarecords * mainwindow->edfheaderlist[0]->long_data_record_duration) / TIME_DIMENSION; time2.setHMS((recording_duration / 3600) % 24, (recording_duration % 3600) / 60, recording_duration % 60, 0); time1Label = new QLabel(averager_dialog); time1Label->setGeometry(20, 65, 100, 25); time1Label->setText("From (hh:mm:ss)"); timeEdit1 = new QTimeEdit(averager_dialog); timeEdit1->setGeometry(130, 65, 110, 25); timeEdit1->setDisplayFormat("hh:mm:ss.zzz"); timeEdit1->setMinimumTime(QTime(0, 0, 0, 0)); timeEdit1->setMaximumTime(time2); time2Label = new QLabel(averager_dialog); time2Label->setGeometry(20, 110, 100, 25); time2Label->setText("To (hh:mm:ss)"); timeEdit2 = new QTimeEdit(averager_dialog); timeEdit2->setGeometry(130, 110, 110, 25); timeEdit2->setDisplayFormat("hh:mm:ss.zzz"); timeEdit2->setMinimumTime(QTime(0, 0, 0, 0)); timeEdit2->setMaximumTime(time2); timeEdit2->setTime(time2); ratioLabel = new QLabel(averager_dialog); ratioLabel->setGeometry(20, 155, 100, 75); ratioLabel->setText("Ratio of time\n" "before and after\n" "trigger:"); ratioBox = new QComboBox(averager_dialog); ratioBox->setGeometry(130, 180, 100, 25); ratioBox->addItem("10 / 90"); ratioBox->addItem("25 / 75"); ratioBox->addItem("50 / 50"); ratioBox->setCurrentIndex(mainwindow->average_ratio); bufsizeLabel = new QLabel(averager_dialog); bufsizeLabel->setGeometry(20, 250, 100, 25); bufsizeLabel->setText("Average period:"); avg_periodspinbox = new QDoubleSpinBox(averager_dialog); avg_periodspinbox->setGeometry(130, 250, 100, 25); avg_periodspinbox->setDecimals(3); avg_periodspinbox->setRange(0.01, 300.0); avg_periodspinbox->setSuffix(" sec"); avg_periodspinbox->setValue(mainwindow->average_period); CloseButton = new QPushButton(averager_dialog); CloseButton->setGeometry(20, 355, 100, 25); CloseButton->setText("Cancel"); StartButton = new QPushButton(averager_dialog); StartButton->setGeometry(310, 355, 100, 25); StartButton->setText("Start"); for(i=0; i<mainwindow->signalcomps; i++) { if(mainwindow->signalcomp[i]->alias[0] != 0) { new QListWidgetItem(mainwindow->signalcomp[i]->alias, list); } else { new QListWidgetItem(mainwindow->signalcomp[i]->signallabel, list); } } list->setCurrentRow(0, QItemSelectionModel::Select); annot = mainwindow->annotationlist[0]; n = annot_nr; while(n) { annot = annot->next_annotation; n--; } strcpy(annot_str, annot->annotation); remove_trailing_spaces(annot_str); annotNameLabel->setText(annot_str); QObject::connect(CloseButton, SIGNAL(clicked()), averager_dialog, SLOT(close())); QObject::connect(StartButton, SIGNAL(clicked()), this, SLOT(startButtonClicked())); averager_dialog->exec(); }
bool RDSvc::import(ImportSource src,const QDate &date,const QString &break_str, const QString &track_str,const QString &dest_table) const { FILE *infile; QString src_str; char buf[RD_MAX_IMPORT_LINE_LENGTH]; QString str_buf; int start_hour; int start_minutes; int start_seconds; QString hours_len_buf; QString minutes_len_buf; QString seconds_len_buf; unsigned cartnum; QString cartname; QString title; QString data_buf; QString eventid_buf; QString annctype_buf; QString os_flag; int cartlen; QString sql; bool ok=false; // // Set Import Source // switch(src) { case RDSvc::Traffic: src_str="TFC"; break; case RDSvc::Music: src_str="MUS"; break; } // // Set OS Type // #ifdef WIN32 os_flag="_WIN"; #endif // // Load Parser Parameters // sql=QString().sprintf("select %s%s_PATH,\ %s_LABEL_CART,\ %s_TRACK_CART,\ %s%s_PREIMPORT_CMD \ from SERVICES where NAME=\"%s\"", (const char *)src_str, (const char *)os_flag, (const char *)src_str, (const char *)src_str, (const char *)src_str, (const char *)os_flag, (const char *)RDEscapeString(svc_name)); RDSqlQuery *q=new RDSqlQuery(sql); if(!q->first()) { delete q; return false; } QString infilename=q->value(0).toString(); QString label_cart=q->value(1).toString().stripWhiteSpace(); QString track_cart=q->value(2).toString().stripWhiteSpace(); QString preimport_cmd=q->value(3).toString(); delete q; // // Open Source File // if((infile=fopen(RDDateDecode(infilename,date),"r"))==NULL) { return false; } // // Run Preimport Command // if(!preimport_cmd.isEmpty()) { system(RDDateDecode(preimport_cmd,date)); } QString parser_table; QString parser_name; if(importTemplate(src).isEmpty()) { src_str+="_"; parser_table="SERVICES"; parser_name=svc_name; } else { src_str=""; parser_table="IMPORT_TEMPLATES"; parser_name=importTemplate(src); } sql=QString("select ")+ src_str+"CART_OFFSET,"+ // 00 src_str+"CART_LENGTH,"+ // 01 src_str+"DATA_OFFSET,"+ // 02 src_str+"DATA_LENGTH,"+ // 03 src_str+"EVENT_ID_OFFSET,"+ // 04 src_str+"EVENT_ID_LENGTH,"+ // 05 src_str+"ANNC_TYPE_OFFSET,"+ // 06 src_str+"ANNC_TYPE_LENGTH,"+ // 07 src_str+"TITLE_OFFSET,"+ // 08 src_str+"TITLE_LENGTH,"+ // 09 src_str+"HOURS_OFFSET,"+ // 10 src_str+"HOURS_LENGTH,"+ // 11 src_str+"MINUTES_OFFSET,"+ // 12 src_str+"MINUTES_LENGTH,"+ // 13 src_str+"SECONDS_OFFSET,"+ // 14 src_str+"SECONDS_LENGTH,"+ // 15 src_str+"LEN_HOURS_OFFSET,"+ // 16 src_str+"LEN_HOURS_LENGTH,"+ // 17 src_str+"LEN_MINUTES_OFFSET,"+ // 18 src_str+"LEN_MINUTES_LENGTH,"+ // 19 src_str+"LEN_SECONDS_OFFSET,"+ // 20 src_str+"LEN_SECONDS_LENGTH "+ // 21 "from "+parser_table+" where NAME=\""+RDEscapeString(parser_name)+"\""; q=new RDSqlQuery(sql); if(!q->first()) { delete q; return false; } int cart_offset=q->value(0).toInt(); int cart_length=q->value(1).toInt(); int data_offset=q->value(2).toInt(); int data_length=q->value(3).toInt(); int eventid_offset=q->value(4).toInt(); int eventid_length=q->value(5).toInt(); int annctype_offset=q->value(6).toInt(); int annctype_length=q->value(7).toInt(); int title_offset=q->value(8).toInt(); int title_length=q->value(9).toInt(); int hours_offset=q->value(10).toInt(); int hours_length=q->value(11).toInt(); int minutes_offset=q->value(12).toInt(); int minutes_length=q->value(13).toInt(); int seconds_offset=q->value(14).toInt(); int seconds_length=q->value(15).toInt(); int hours_len_offset=q->value(16).toInt(); int hours_len_length=q->value(17).toInt(); int minutes_len_offset=q->value(18).toInt(); int minutes_len_length=q->value(19).toInt(); int seconds_len_offset=q->value(20).toInt(); int seconds_len_length=q->value(21).toInt(); delete q; // // Setup Data Source and Destination // sql=QString().sprintf("drop table `%s`",(const char *)dest_table); QSqlQuery *qq; // Use QSqlQuery so we don't generate a qq=new QSqlQuery(sql); // spurious error message. delete qq; sql=QString("create table ")+ "`"+dest_table+"` ("+ "ID int primary key,"+ "START_HOUR int not null,"+ "START_SECS int not null,"+ "CART_NUMBER int unsigned,"+ "TITLE char(255),"+ "LENGTH int,"+ "INSERT_BREAK enum('N','Y') default 'N',"+ "INSERT_TRACK enum('N','Y') default 'N',"+ "INSERT_FIRST int unsigned default 0,"+ "TRACK_STRING char(255),"+ "EXT_DATA char(32),"+ "EXT_EVENT_ID char(32),"+ "EXT_ANNC_TYPE char(8),"+ "EXT_CART_NAME char(32),"+ "LINK_START_TIME time default NULL,"+ "LINK_LENGTH int default NULL,"+ "EVENT_USED enum('N','Y') default 'N',"+ "INDEX START_TIME_IDX (START_HOUR,START_SECS))"; q=new RDSqlQuery(sql); delete q; // // Parse and Save // int line_id=0; bool insert_found=false; bool cart_ok=false; bool start_time_ok=false; bool line_used=false; bool insert_break=false; bool insert_track=false; bool break_first=false; bool track_first=false; QString track_label; QTime link_time; int link_length=-1; while(fgets(buf,RD_MAX_IMPORT_LINE_LENGTH,infile)!=NULL) { line_used=false; str_buf=QString(buf); // // Cart Number // cartnum=0; cartname=str_buf.mid(cart_offset,cart_length).stripWhiteSpace(); // // Start Time // start_time_ok=true; start_hour=str_buf.mid(hours_offset,hours_length).toInt(&ok); if((!ok)||(start_hour<0)||(start_hour>23)) { start_time_ok=false; } start_minutes=str_buf.mid(minutes_offset,minutes_length).toInt(&ok); if((!ok)||(start_minutes<0)) { start_time_ok=false; } start_seconds=str_buf.mid(seconds_offset,seconds_length).toInt(&ok); if((!ok)||(start_seconds<0)||(start_seconds>59)) { start_time_ok=false; } // // Length // hours_len_buf=str_buf.mid(hours_len_offset,hours_len_length); minutes_len_buf=str_buf.mid(minutes_len_offset,minutes_len_length); seconds_len_buf=str_buf.mid(seconds_len_offset,seconds_len_length); cartlen=3600000*hours_len_buf.toInt()+60000*minutes_len_buf.toInt()+ 1000*seconds_len_buf.toInt(); // // External Data // data_buf=str_buf.mid(data_offset,data_length); eventid_buf=str_buf.mid(eventid_offset,eventid_length); annctype_buf=str_buf.mid(annctype_offset,annctype_length); // // Title // title=str_buf.mid(title_offset,title_length).stripWhiteSpace(); // // Process Line // cartnum=cartname.toUInt(&cart_ok); if(start_time_ok&&(cart_ok|| ((!label_cart.isEmpty())&&(cartname==label_cart))|| ((!track_cart.isEmpty())&&(cartname==track_cart)))) { sql=QString("insert into ")+ "`"+dest_table+"` set "+ QString().sprintf("ID=%d,",line_id++)+ QString().sprintf("START_HOUR=%d,",start_hour)+ QString().sprintf("START_SECS=%d,", 60*start_minutes+start_seconds)+ QString().sprintf("CART_NUMBER=%u,",cartnum)+ "TITLE=\""+RDEscapeString(title)+"\","+ QString().sprintf("LENGTH=%d,",cartlen)+ "EXT_DATA=\""+data_buf+"\","+ "EXT_EVENT_ID=\""+eventid_buf+"\","+ "EXT_ANNC_TYPE=\""+annctype_buf+"\","+ "EXT_CART_NAME=\""+cartname+"\""; q=new RDSqlQuery(sql); delete q; // // Insert Break // if(insert_break) { sql=QString("update ")+"`"+dest_table+"` set "+ "INSERT_BREAK=\"Y\""; if(break_first) { sql+=QString().sprintf(",INSERT_FIRST=%d", RDEventLine::InsertBreak); } if(link_time.isValid()&&(link_length>=0)) { sql+=",LINK_START_TIME=\""+ link_time.toString("hh:mm:ss")+"\""+ QString().sprintf(",LINK_LENGTH=%d", link_length); } sql+=QString().sprintf(" where ID=%d",line_id-1); q=new RDSqlQuery(sql); delete q; } // // Insert Track // if(insert_track) { if(track_first) { sql=QString("update ")+ "`"+dest_table+"` set "+ "INSERT_TRACK=\"Y\","+ "TRACK_STRING=\""+RDEscapeString(track_label)+"\","+ QString().sprintf("INSERT_FIRST=%d ",RDEventLine::InsertTrack)+ QString().sprintf("where ID=%d",line_id-1); } else { sql=QString("update ")+ "`"+dest_table+"` set "+ "INSERT_TRACK=\"Y\","+ "TRACK_STRING=\""+RDEscapeString(track_label)+"\" "+ QString().sprintf("where ID=%d",line_id-1); } q=new RDSqlQuery(sql); delete q; } insert_break=false; break_first=false; insert_track=false; track_first=false; insert_found=false; line_used=true; } if((cartname==break_str)&&start_time_ok) { link_time= QTime(start_hour,start_minutes,start_seconds); link_length=cartlen; } else { link_time=QTime(); link_length=-1; } if(!line_used) { // // Look for Break and Track Strings // if(!break_str.isEmpty()) { if(str_buf.contains(break_str)) { insert_break=true; if(!insert_found) { break_first=true; insert_found=true; } } } if(!track_str.isEmpty()) { if(str_buf.contains(track_str)) { insert_track=true; track_label=str_buf; if(!insert_found) { track_first=true; insert_found=true; } } } } } // // Cleanup // fclose(infile); return true; }
void ProgDetails::loadPage(void) { loadHTML(); MSqlQuery query(MSqlQuery::InitCon()); QString category_type, showtype, year, epinum, rating, colorcode, title_pronounce; float stars = 0.0; int partnumber = 0, parttotal = 0; int audioprop = 0, videoprop = 0, subtype = 0, generic = 0; bool recorded = false; RecordingRule* record = NULL; if (m_progInfo.GetRecordingRuleID()) { record = new RecordingRule(); record->LoadByProgram(&m_progInfo); } if (m_progInfo.GetFilesize()) recorded = true; if (m_progInfo.GetScheduledEndTime() != m_progInfo.GetScheduledStartTime()) { QString ptable = "program"; if (recorded) ptable = "recordedprogram"; query.prepare(QString("SELECT category_type, airdate, stars," " partnumber, parttotal, audioprop+0, videoprop+0," " subtitletypes+0, syndicatedepisodenumber, generic," " showtype, colorcode, title_pronounce" " FROM %1 WHERE chanid = :CHANID AND" " starttime = :STARTTIME ;").arg(ptable)); query.bindValue(":CHANID", m_progInfo.GetChanID()); query.bindValue(":STARTTIME", m_progInfo.GetScheduledStartTime()); if (query.exec() && query.next()) { category_type = query.value(0).toString(); year = query.value(1).toString(); stars = query.value(2).toDouble(); partnumber = query.value(3).toInt(); parttotal = query.value(4).toInt(); audioprop = query.value(5).toInt(); videoprop = query.value(6).toInt(); subtype = query.value(7).toInt(); epinum = query.value(8).toString(); generic = query.value(9).toInt(); showtype = query.value(10).toString(); colorcode = query.value(11).toString(); title_pronounce = query.value(12).toString(); } else if (!query.isActive()) MythDB::DBError("ProgDetails", query); rating = getRatings( recorded, m_progInfo.GetChanID(), m_progInfo.GetScheduledStartTime()); } if (category_type.isEmpty() && !m_progInfo.GetProgramID().isEmpty()) { QString prefix = m_progInfo.GetProgramID().left(2); if (prefix == "MV") category_type = "movie"; else if (prefix == "EP") category_type = "series"; else if (prefix == "SP") category_type = "sports"; else if (prefix == "SH") category_type = "tvshow"; } addItem("TITLE", tr("Title"), m_progInfo.toString(ProgramInfo::kTitleSubtitle, " - ")); addItem("TITLE_PRONOUNCE", tr("Title Pronounce"), title_pronounce); QString s = m_progInfo.GetDescription(); QString attr; if (partnumber > 0) attr += QString(tr("Part %1 of %2, ")).arg(partnumber).arg(parttotal); if (!rating.isEmpty() && rating != "NR") attr += rating + ", "; if (category_type == "movie") { if (!year.isEmpty()) attr += year + ", "; if (stars > 0.0) attr += tr("%n star(s)", "", (int) (stars * 4.0)) + ", "; } if (!colorcode.isEmpty()) attr += colorcode + ", "; if (audioprop & AUD_MONO) attr += tr("Mono") + ", "; if (audioprop & AUD_STEREO) attr += tr("Stereo") + ", "; if (audioprop & AUD_SURROUND) attr += tr("Surround Sound") + ", "; if (audioprop & AUD_DOLBY) attr += tr("Dolby Sound") + ", "; if (audioprop & AUD_HARDHEAR) attr += tr("Audio for Hearing Impaired") + ", "; if (audioprop & AUD_VISUALIMPAIR) attr += tr("Audio for Visually Impaired") + ", "; if (videoprop & VID_HDTV) attr += tr("HDTV") + ", "; if (videoprop & VID_WIDESCREEN) attr += tr("Widescreen") + ", "; if (videoprop & VID_AVC) attr += tr("AVC/H.264") + ", "; if (videoprop & VID_720) attr += tr("720p Resolution") + ", "; if (videoprop & VID_1080) attr += tr("1080i/p Resolution") + ", "; if (subtype & SUB_HARDHEAR) attr += tr("CC","Closed Captioned") + ", "; if (subtype & SUB_NORMAL) attr += tr("Subtitles Available") + ", "; if (subtype & SUB_ONSCREEN) attr += tr("Subtitled") + ", "; if (subtype & SUB_SIGNED) attr += tr("Deaf Signing") + ", "; if (generic && category_type == "series") attr += tr("Unidentified Episode") + ", "; else if (m_progInfo.IsRepeat()) attr += tr("Repeat") + ", "; if (!attr.isEmpty()) { attr.truncate(attr.lastIndexOf(',')); s += " (" + attr + ")"; } addItem("DESCRIPTION", tr("Description"), s); s.clear(); if (!m_progInfo.GetCategory().isEmpty()) { s = m_progInfo.GetCategory(); query.prepare("SELECT genre FROM programgenres " "WHERE chanid = :CHANID AND starttime = :STARTTIME " "AND relevance > 0 ORDER BY relevance;"); query.bindValue(":CHANID", m_progInfo.GetChanID()); query.bindValue(":STARTTIME", m_progInfo.GetScheduledStartTime()); if (query.exec()) { while (query.next()) s += ", " + query.value(0).toString(); } } addItem("CATEGORY", tr("Category"), s); s.clear(); if (!category_type.isEmpty()) { s = category_type; if (!m_progInfo.GetSeriesID().isEmpty()) s += " (" + m_progInfo.GetSeriesID() + ")"; if (!showtype.isEmpty()) s += " " + showtype; } addItem("CATEGORY_TYPE", tr("Type", "category_type"), s); addItem("EPISODE", tr("Episode Number"), epinum); s.clear(); if (m_progInfo.GetOriginalAirDate().isValid() && category_type != "movie") { s = MythDate::toString(m_progInfo.GetOriginalAirDate(), MythDate::kDateFull | MythDate::kAddYear); } addItem("ORIGINAL_AIRDATE", tr("Original Airdate"), s); addItem("PROGRAMID", tr("Program ID"), m_progInfo.GetProgramID()); QString actors, directors, producers, execProducers; QString writers, guestStars, hosts, adapters; QString presenters, commentators, guests; if (m_progInfo.GetScheduledEndTime() != m_progInfo.GetScheduledStartTime()) { if (recorded) query.prepare("SELECT role,people.name FROM recordedcredits" " AS credits" " LEFT JOIN people ON credits.person = people.person" " WHERE credits.chanid = :CHANID" " AND credits.starttime = :STARTTIME" " ORDER BY role;"); else query.prepare("SELECT role,people.name FROM credits" " LEFT JOIN people ON credits.person = people.person" " WHERE credits.chanid = :CHANID" " AND credits.starttime = :STARTTIME" " ORDER BY role;"); query.bindValue(":CHANID", m_progInfo.GetChanID()); query.bindValue(":STARTTIME", m_progInfo.GetScheduledStartTime()); if (query.exec() && query.size() > 0) { QStringList plist; QString rstr, role, pname; while(query.next()) { role = query.value(0).toString(); /* The people.name column uses utf8_bin collation. * Qt-MySQL drivers use QVariant::ByteArray for string-type * MySQL fields marked with the BINARY attribute (those using a * *_bin collation) and QVariant::String for all others. * Since QVariant::toString() uses QString::fromAscii() * (through QVariant::convert()) when the QVariant's type is * QVariant::ByteArray, we have to use QString::fromUtf8() * explicitly to prevent corrupting characters. * The following code should be changed to use the simpler * toString() approach, as above, if we do a DB update to * coalesce the people.name values that differ only in case and * change the collation to utf8_general_ci, to match the * majority of other columns, or we'll have the same problem in * reverse. */ pname = QString::fromUtf8(query.value(1) .toByteArray().constData()); if (rstr != role) { if (rstr == "actor") actors = plist.join(", "); else if (rstr == "director") directors = plist.join(", "); else if (rstr == "producer") producers = plist.join(", "); else if (rstr == "executive_producer") execProducers = plist.join(", "); else if (rstr == "writer") writers = plist.join(", "); else if (rstr == "guest_star") guestStars = plist.join(", "); else if (rstr == "host") hosts = plist.join(", "); else if (rstr == "adapter") adapters = plist.join(", "); else if (rstr == "presenter") presenters = plist.join(", "); else if (rstr == "commentator") commentators = plist.join(", "); else if (rstr == "guest") guests = plist.join(", "); rstr = role; plist.clear(); } plist.append(pname); } if (rstr == "actor") actors = plist.join(", "); else if (rstr == "director") directors = plist.join(", "); else if (rstr == "producer") producers = plist.join(", "); else if (rstr == "executive_producer") execProducers = plist.join(", "); else if (rstr == "writer") writers = plist.join(", "); else if (rstr == "guest_star") guestStars = plist.join(", "); else if (rstr == "host") hosts = plist.join(", "); else if (rstr == "adapter") adapters = plist.join(", "); else if (rstr == "presenter") presenters = plist.join(", "); else if (rstr == "commentator") commentators = plist.join(", "); else if (rstr == "guest") guests = plist.join(", "); } } addItem("ACTORS", tr("Actors"), actors); addItem("DIRECTOR", tr("Director"), directors); addItem("PRODUCER", tr("Producer"), producers); addItem("EXECUTIVE_PRODUCER", tr("Executive Producer"), execProducers); addItem("WRITER", tr("Writer"), writers); addItem("GUEST_STAR", tr("Guest Star"), guestStars); addItem("HOST", tr("Host"), hosts); addItem("ADAPTER", tr("Adapter"), adapters); addItem("PRESENTER", tr("Presenter"), presenters); addItem("COMMENTATOR", tr("Commentator"), commentators); addItem("GUEST", tr("Guest"), guests); // Begin MythTV information not found in the listings info // msg += "<br>"; QDateTime statusDate; if (m_progInfo.GetRecordingStatus() == rsWillRecord) statusDate = m_progInfo.GetScheduledStartTime(); RecordingType rectype = kSingleRecord; // avoid kNotRecording RecStatusType recstatus = m_progInfo.GetRecordingStatus(); if (recstatus == rsPreviousRecording || recstatus == rsNeverRecord || recstatus == rsUnknown) { query.prepare("SELECT recstatus, starttime " "FROM oldrecorded WHERE duplicate > 0 AND " "future = 0 AND " "((programid <> '' AND programid = :PROGRAMID) OR " " (title <> '' AND title = :TITLE AND " " subtitle <> '' AND subtitle = :SUBTITLE AND " " description <> '' AND description = :DECRIPTION));"); query.bindValue(":PROGRAMID", m_progInfo.GetProgramID()); query.bindValue(":TITLE", m_progInfo.GetTitle()); query.bindValue(":SUBTITLE", m_progInfo.GetSubtitle()); query.bindValue(":DECRIPTION", m_progInfo.GetDescription()); if (!query.exec()) { MythDB::DBError("showDetails", query); } else if (query.next()) { if (recstatus == rsUnknown) recstatus = RecStatusType(query.value(0).toInt()); if (recstatus == rsPreviousRecording || recstatus == rsNeverRecord || recstatus == rsRecorded) { statusDate = MythDate::as_utc(query.value(1).toDateTime()); } } } if (recstatus == rsUnknown) { if (recorded) { recstatus = rsRecorded; statusDate = m_progInfo.GetScheduledStartTime(); } else { // re-enable "Not Recording" status text rectype = m_progInfo.GetRecordingRuleType(); } } s = toString(recstatus, rectype); if (statusDate.isValid()) s += " " + MythDate::toString(statusDate, MythDate::kDateFull | MythDate::kAddYear); addItem("MYTHTV_STATUS", tr("MythTV Status"), s); QString recordingRule; QString lastRecorded; QString nextRecording; QString averageTimeShift; QString watchListScore; QString watchListStatus; QString searchPhrase; if (m_progInfo.GetRecordingRuleID()) { recordingRule = QString("%1, ").arg(m_progInfo.GetRecordingRuleID()); if (m_progInfo.GetRecordingRuleType() != kNotRecording) recordingRule += toString(m_progInfo.GetRecordingRuleType()); if (!(record->m_title.isEmpty())) recordingRule += QString(" \"%2\"").arg(record->m_title); query.prepare("SELECT last_record, next_record, avg_delay " "FROM record WHERE recordid = :RECORDID"); query.bindValue(":RECORDID", m_progInfo.GetRecordingRuleID()); if (query.exec() && query.next()) { if (query.value(0).toDateTime().isValid()) lastRecorded = MythDate::toString( MythDate::as_utc(query.value(0).toDateTime()), MythDate::kDateFull | MythDate::kAddYear); if (query.value(1).toDateTime().isValid()) nextRecording = MythDate::toString( MythDate::as_utc(query.value(1).toDateTime()), MythDate::kDateFull | MythDate::kAddYear); if (query.value(2).toInt() > 0) averageTimeShift = tr("%n hour(s)", "", query.value(2).toInt()); } if (recorded) { if (m_progInfo.GetRecordingPriority2() > 0) watchListScore = QString::number(m_progInfo.GetRecordingPriority2()); if (m_progInfo.GetRecordingPriority2() < 0) { switch (m_progInfo.GetRecordingPriority2()) { case wlExpireOff: watchListStatus = tr("Auto-expire off"); break; case wlWatched: watchListStatus = tr("Marked as 'watched'"); break; case wlEarlier: watchListStatus = tr("Not the earliest episode"); break; case wlDeleted: watchListStatus = tr("Recently deleted episode"); break; } } } if (record->m_searchType != kManualSearch && record->m_description != m_progInfo.GetDescription()) { searchPhrase = record->m_description .replace("<", "<").replace(">", ">").replace("\n", " "); } } addItem("RECORDING_RULE", tr("Recording Rule"), recordingRule); addItem("LAST_RECORDED", tr("Last Recorded"), lastRecorded); addItem("NEXT_RECORDING", tr("Next Recording"), nextRecording); addItem("AVERAGE_TIME_SHIFT", tr("Average Time Shift"), averageTimeShift); addItem("WATCH_LIST_SCORE", tr("Watch List Score"), watchListScore); addItem("WATCH_LIST_STATUS", tr("Watch List Status"), watchListStatus); addItem("SEARCH_PHRASE", tr("Search Phrase"), searchPhrase); s.clear(); if (m_progInfo.GetFindID()) { QDateTime fdate(QDate(1970, 1, 1),QTime(12,0,0)); fdate = fdate.addDays((int)m_progInfo.GetFindID() - 719528); s = QString("%1 (%2)").arg(m_progInfo.GetFindID()) .arg(MythDate::toString( fdate, MythDate::kDateFull | MythDate::kAddYear)); } addItem("FINDID", tr("Find ID"), s); QString recordingHost; QString recordedFilename; QString recordedFileSize; QString recordingGroup; QString storageGroup; QString playbackGroup; QString recordingProfile; if (recorded) { recordingHost = m_progInfo.GetHostname(); recordedFilename = m_progInfo.GetBasename(); recordedFileSize = QString("%1 ") .arg(m_progInfo.GetFilesize()/((double)(1<<30)),0,'f',2); recordedFileSize += tr("GB", "GigaBytes"); query.prepare("SELECT profile FROM recorded" " WHERE chanid = :CHANID" " AND starttime = :STARTTIME;"); query.bindValue(":CHANID", m_progInfo.GetChanID()); query.bindValue(":STARTTIME", m_progInfo.GetRecordingStartTime()); if (query.exec() && query.next()) { recordingProfile = m_progInfo.i18n(query.value(0).toString()); } recordingGroup = m_progInfo.i18n(m_progInfo.GetRecordingGroup()); storageGroup = m_progInfo.i18n(m_progInfo.GetStorageGroup()); playbackGroup = m_progInfo.i18n(m_progInfo.GetPlaybackGroup()); } else if (m_progInfo.GetRecordingRuleID()) { recordingProfile = record->m_recProfile; } addItem("RECORDING_HOST", tr("Recording Host"), recordingHost); addItem("RECORDED_FILE_NAME", tr("Recorded File Name"), recordedFilename); addItem("RECORDED_FILE_SIZE", tr("Recorded File Size"), recordedFileSize); addItem("RECORDING_PROFILE", tr("Recording Profile"), recordingProfile); addItem("RECORDING_GROUP", tr("Recording Group"), recordingGroup); addItem("STORAGE_GROUP", tr("Storage Group"), storageGroup); addItem("PLAYBACK_GROUP", tr("Playback Group"), playbackGroup); m_page[m_currentPage] = m_html.join("\n"); delete record; }
void tst_QDjangoHttpController::testDateTime() { const QDateTime dt(QDate(2014, 7, 14), QTime(11, 22, 33), Qt::UTC); QCOMPARE(QDjangoHttpController::httpDateTime(dt), QString("Mon, 14 Jul 2014 11:22:33 GMT")); QCOMPARE(QDjangoHttpController::httpDateTime("Mon, 14 Jul 2014 11:22:33 GMT"), dt); }
void Group8Strategy::processTrade(const Trade &t) { if (m_magic.contains(t.instrument())) { MagicData &data = m_magic[t.instrument()]; if (t.price() >= data.previousPrice) { if (data.isRising == false) { data.currentConsecutiveChanges = 0; } data.isRising = true; } else { if (data.isRising == true) { data.currentConsecutiveChanges = 0; } data.isRising = false; } data.previousPrice = t.price(); data.previousVolume = t.volume(); data.currentConsecutiveChanges++; if (5 <= data.currentConsecutiveChanges && t.time().secsTo(QTime(16,00)) >= 50) { data.currentConsecutiveChanges = 0; if (data.isRising) { auto r = Record::Ptr::create(); r->setBidId(6666); r->setAskId(0); r->setBidOrAsk(Record::BidAsk::Bid); r->setDate(t.date()); r->setTime(t.time()); r->setInstrument(t.instrument()); r->setType(Record::Type::ENTER); r->setVolume(data.previousVolume); r->setPrice(t.price()); r->setValue(r->price() * r->volume()); emit newRecordCreated(r); qDebug() << "created a bid"; //this is bad data.totalBought += data.previousVolume; } else { auto r = Record::Ptr::create(); r->setAskId(6666); r->setBidId(0); r->setBidOrAsk(Record::BidAsk::Ask); r->setDate(t.date()); r->setTime(t.time()); r->setInstrument(t.instrument()); r->setType(Record::Type::ENTER); r->setVolume(data.totalBought-data.totalSold); r->setPrice(t.price()); r->setValue(r->price() * r->volume()); emit newRecordCreated(r); qDebug() << "created a ask"; //this is bad. data.totalSold += data.totalBought-data.totalSold; } } //qDebug() << abs(QTime(15,40).secsTo(t.time())); //qDebug() <<(data.totalBought-data.totalSold); if( abs(QTime(16,00).secsTo(t.time())) < 50 && (data.totalBought-data.totalSold) > 0) { qDebug() << data.totalBought-data.totalSold; data.currentConsecutiveChanges = 0; auto r = Record::Ptr::create(); r->setAskId(6666); r->setBidId(0); r->setBidOrAsk(Record::BidAsk::Ask); r->setDate(t.date()); r->setTime(t.time()); r->setInstrument(t.instrument()); r->setType(Record::Type::ENTER); r->setVolume(data.totalBought-data.totalSold); r->setPrice(t.price()); r->setValue(r->price() * r->volume()); emit newRecordCreated(r); //this is bad. data.totalSold += data.totalBought-data.totalSold; } } }
//========== // PRIVATE // ========== void LPConfig::loadDatasetConfiguration(QString dataset, bool replicated){ qDebug() <<" - Loading dataset configuration:" << dataset; //Load the dataset values isReplicated = replicated; // - Local settings if( !LPBackend::datasetInfo(dataset, localSchedule, localSnapshots) ){ localSchedule = 1; //daily at 1 AM localSnapshots = 7; } // - Replication settings bool ok=false; if(isReplicated){ ok = LPBackend::replicationInfo(dataset, remoteHost, remoteUser, remotePort, remoteDataset, remoteFreq); } if(!ok){ isReplicated = false; remotePort = 22; remoteFreq = -1; //sync remoteHost = ""; remoteUser = ""; remoteDataset = ""; } //Now put the values into the UI // - local settings if(localSchedule == -5){ //5 minutes ui->combo_local_schedule->setCurrentIndex(5); }else if(localSchedule == -10){ //10 minutes ui->combo_local_schedule->setCurrentIndex(4); }else if(localSchedule == -30){ //30 minutes ui->combo_local_schedule->setCurrentIndex(3); }else if(localSchedule == -60){ //assume hourly ui->combo_local_schedule->setCurrentIndex(2); }else if(localSchedule > 0 && localSchedule < 24){ //daily @ hour ui->combo_local_schedule->setCurrentIndex(1); ui->time_local_daily->setTime( QTime(localSchedule, 0) ); }else{ //assume auto localSchedule = -999; //just to make sure it does not match anything else ui->combo_local_schedule->setCurrentIndex(0); } setLocalKeepNumber(); // - Replication settings ui->groupReplicate->setChecked(isReplicated); ui->lineHostName->setText(remoteHost); ui->lineUserName->setText(remoteUser); ui->lineRemoteDataset->setText(remoteDataset); ui->spinPort->setValue(remotePort); if(remoteFreq >=0 && remoteFreq < 24){ ui->combo_remote_schedule->setCurrentIndex(1); //Daily @ ui->time_replicate->setTime( QTime(remoteFreq,0) ); }else if(remoteFreq == -60){ ui->combo_remote_schedule->setCurrentIndex(2); //Hourly }else if(remoteFreq == -30){ ui->combo_remote_schedule->setCurrentIndex(3); // 30 minutes }else if(remoteFreq == -10){ ui->combo_remote_schedule->setCurrentIndex(4); // 10 minutes }else if(remoteFreq == -2){ ui->combo_remote_schedule->setCurrentIndex(5); // Manual mode }else{ remoteFreq = -999; //just to make sure it is the "other" case ui->combo_remote_schedule->setCurrentIndex(0); // Sync } //Now update the visibility of items appropriately on_combo_local_schedule_currentIndexChanged(ui->combo_local_schedule->currentIndex()); on_combo_remote_schedule_currentIndexChanged(ui->combo_remote_schedule->currentIndex()); }
void modCalcJD::processLines( QTextStream &istream, int inputData ) { QFile fOut( OutputFileBatch->url().toLocalFile() ); fOut.open(QIODevice::WriteOnly); QTextStream ostream(&fOut); QString line; long double jd(0); double mjd(0); KStarsDateTime dt; while ( ! istream.atEnd() ) { line = istream.readLine(); line = line.trimmed(); QStringList data = line.split( ' ', QString::SkipEmptyParts ); if ( inputData == 0 ) { //Parse date & time //Is the first field parseable as a date or date&time? if ( data[0].length() > 10 ) dt = KStarsDateTime::fromString( data[0] ); else dt = KStarsDateTime( QDate::fromString( data[0] ), QTime(0,0,0) ); //DEBUG kDebug() << data[0]; if ( dt.isValid() ) kDebug() << dt.toString(); if ( dt.isValid() ) { //Try to parse the second field as a time if ( data.size() > 1 ) { QString s = data[1]; if ( s.length() == 4 ) s = '0'+s; QTime t = QTime::fromString( s ); if ( t.isValid() ) dt.setTime( t ); } } else { //Did not parse the first field as a date; try it as a time QTime t = QTime::fromString( data[0] ); if ( t.isValid() ) { dt.setTime( t ); //Now try the second field as a date if ( data.size() > 1 ) { QDate d = QDate::fromString( data[1] ); if ( d.isValid() ) dt.setDate( d ); else dt.setDate( QDate::currentDate() ); } } } if ( dt.isValid() ) { //Compute JD and MJD jd = dt.djd(); mjd = jd - MJD0; } } else if ( inputData == 1 ) {//Parse Julian day bool ok(false); jd = data[0].toDouble(&ok); if ( ok ) { dt.setDJD( jd ); mjd = jd - MJD0; } } else if ( inputData == 2 ) {//Parse Modified Julian day bool ok(false); mjd = data[0].toDouble(&ok); if ( ok ) { jd = mjd + MJD0; dt.setDJD( jd ); } } //Write to output file ostream << KGlobal::locale()->formatDateTime( dt, KLocale::LongDate ) << " " << QString::number( jd, 'f', 2 ) << " " << QString::number( mjd, 'f', 2 ) << endl; } fOut.close(); }
void DayPage::refresh() { m_dateLabel->setText(m_day.toString()); m_itemList->clear(); // Today's item QList<QOrganizerItem> items = m_manager->items(QDateTime(m_day), QDateTime(m_day, QTime(23, 59, 59))); foreach (const QOrganizerItem &item, items) { QOrganizerEventTime eventTime = item.detail<QOrganizerEventTime>(); if (!eventTime.isEmpty()) { QString time = eventTime.startDateTime().time().toString("hh:mm"); QListWidgetItem* listItem = new QListWidgetItem(); if (item.type() == QOrganizerItemType::TypeEventOccurrence) listItem->setText(QString("Event occurrence:%1-%2").arg(time).arg(item.displayLabel())); else listItem->setText(QString("Event:%1-%2").arg(time).arg(item.displayLabel())); QVariant data = QVariant::fromValue<QOrganizerItem>(item); listItem->setData(ORGANIZER_ITEM_ROLE, data); m_itemList->addItem(listItem); } QOrganizerTodoTime todoTime = item.detail<QOrganizerTodoTime>(); if (!todoTime.isEmpty()) { QString time = todoTime.startDateTime().time().toString("hh:mm"); QListWidgetItem* listItem = new QListWidgetItem(); listItem->setText(QString("Todo:%1-%2").arg(time).arg(item.displayLabel())); QVariant data = QVariant::fromValue<QOrganizerItem>(item); listItem->setData(ORGANIZER_ITEM_ROLE, data); m_itemList->addItem(listItem); } QOrganizerJournalTime journalTime = item.detail<QOrganizerJournalTime>(); if (!journalTime.isEmpty()) { QString time = journalTime.entryDateTime().time().toString("hh:mm"); QListWidgetItem* listItem = new QListWidgetItem(); listItem->setText(QString("Journal:%1-%2").arg(time).arg(item.displayLabel())); QVariant data = QVariant::fromValue<QOrganizerItem>(item); listItem->setData(ORGANIZER_ITEM_ROLE, data); m_itemList->addItem(listItem); } // TODO: other item types }
UI_JumpMenuDialog::UI_JumpMenuDialog(QWidget *w_parent) { mainwindow = (UI_Mainwindow *)w_parent; jump_dialog = new QDialog(w_parent); jump_dialog->setMinimumSize(QSize(435, 200)); jump_dialog->setMaximumSize(QSize(435, 200)); jump_dialog->setWindowTitle("Jump to"); jump_dialog->setModal(TRUE); jump_dialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); label1 = new QLabel(jump_dialog); label1->setGeometry(QRect(10, 10, 155, 25)); label1->setText(" dd hh:mm:ss.ms "); daybox1 = new QSpinBox(jump_dialog); daybox1->setGeometry(QRect(10, 45, 45, 25)); daybox1->setRange(0, 30); daybox1->setEnabled(FALSE); daybox2 = new QSpinBox(jump_dialog); daybox2->setGeometry(QRect(10, 80, 45, 25)); daybox2->setRange(0, 30); daybox2->setEnabled(FALSE); timeEdit1 = new QTimeEdit(jump_dialog); timeEdit1->setGeometry(QRect(65, 45, 110, 25)); timeEdit1->setDisplayFormat("hh:mm:ss.zzz"); timeEdit1->setMinimumTime(QTime(0, 0, 0, 0)); timeEdit1->setEnabled(FALSE); timeEdit2 = new QTimeEdit(jump_dialog); timeEdit2->setGeometry(QRect(65, 80, 110, 25)); timeEdit2->setDisplayFormat("hh:mm:ss.zzz"); timeEdit2->setMinimumTime(QTime(0, 0, 0, 0)); timeEdit2->setEnabled(FALSE); label2 = new QLabel("Offset from start of recording", jump_dialog); label2->setGeometry(QRect(185, 45, 250, 25)); label3 = new QLabel("Absolute time", jump_dialog); label3->setGeometry(QRect(185, 80, 250, 25)); jumpButton = new QPushButton(jump_dialog); jumpButton->setGeometry(QRect(10, 165, 100, 25)); jumpButton->setText("Jump"); jumpButton->setEnabled(FALSE); CloseButton = new QPushButton(jump_dialog); CloseButton->setGeometry(QRect(325, 165, 100, 25)); CloseButton->setText("Cancel"); if(mainwindow->files_open) { daybox1->setEnabled(TRUE); daybox2->setEnabled(TRUE); timeEdit1->setEnabled(TRUE); timeEdit2->setEnabled(TRUE); starttime = mainwindow->edfheaderlist[mainwindow->sel_viewtime]->l_starttime + mainwindow->edfheaderlist[mainwindow->sel_viewtime]->starttime_offset; starttime /= 10000; time2.setHMS((int)((starttime / 3600000LL) % 24LL), (int)((starttime % 3600000LL) / 60000LL), (int)((starttime % 60000LL) / 1000LL), (int)(starttime % 1000LL)); timeEdit2->setMinimumTime(QTime((int)((starttime / 3600000LL) % 24LL), (int)((starttime % 3600000LL) / 60000LL), (int)((starttime % 60000LL) / 1000LL), (int)(starttime % 1000LL))); timeEdit2->setTime(time2); recording_duration = mainwindow->edfheaderlist[0]->datarecords * mainwindow->edfheaderlist[0]->long_data_record_duration; recording_duration /= (TIME_DIMENSION / 1000LL); jumpButton->setEnabled(TRUE); } QObject::connect(CloseButton, SIGNAL(clicked()), jump_dialog, SLOT(close())); QObject::connect(jumpButton, SIGNAL(clicked()), this, SLOT(jumpbutton_pressed())); QObject::connect(timeEdit1, SIGNAL(timeChanged(const QTime &)), this, SLOT(offsettime_changed(const QTime &))); QObject::connect(timeEdit2, SIGNAL(timeChanged(const QTime &)), this, SLOT(absolutetime_changed(const QTime &))); QObject::connect(daybox1, SIGNAL(valueChanged(int)), this, SLOT(offsetday_changed(int))); QObject::connect(daybox2, SIGNAL(valueChanged(int)), this, SLOT(absoluteday_changed(int))); jump_dialog->exec(); }
QString read_item( const Outlook::_AppointmentItemPtr &item, QXmlStreamReader &reader, bool dump_exception ) { TRACE(OutlookSyncPlugin) << "OutlookDatebookSync::read_item"; Outlook::UserPropertiesPtr props = item->GetUserProperties(); Q_ASSERT(props); // We need to clear the recurrence pattern now or we will fail to update recurring events if ( !dump_exception ) item->ClearRecurrencePattern(); enum State { Idle, When, Alarm, Repeat, Exception, Categories }; State state = Idle; Outlook::RecurrencePatternPtr recpat = 0; QString key; QXmlStreamAttributes attributes; QString value; QStringList categories; bool utc = false; bool allday = false; while (!reader.atEnd()) { bool loop = true; switch(reader.readNext()) { case QXmlStreamReader::StartElement: key = reader.qualifiedName().toString(); value = QString(); attributes = reader.attributes(); if ( key == "When" ) state = When; if ( state == When && key == "StartDate" ) { allday = true; } if ( state == When && key == "Start" ) { allday = false; } if ( key == "Alarm" ) { state = Alarm; LOG() << "item->PutReminderSet" << false; item->PutReminderSet( false ); } if ( state == Alarm && key == "Type" || key == "Delay" ) { // Outlook only wants to see alarms set on events in the future // If we sync an event in the past with an alarm it will go off // immediately, something that can be annoying when you do an // initial sync with lots of events with alarms. if ( date_to_qdatetime(item->GetStart()) > QDateTime::currentDateTime() ) { LOG() << "item->PutReminderSet" << true; item->PutReminderSet( true ); } } if ( !dump_exception ) { if ( key == "Repeat" ) { state = Repeat; } if ( state == Repeat && key == "Type" ) { recpat = item->GetRecurrencePattern(); recpat->PutPatternStartDate( item->GetStart() ); } if ( state == Repeat && key == "Exception" ) { state = Exception; } } if ( key == "Categories" ) state = Categories; break; case QXmlStreamReader::Characters: value += reader.text().toString(); break; case QXmlStreamReader::EndElement: key = reader.qualifiedName().toString(); //LOG() << "key" << key << "value" << value; READ_STRING(Description,Subject); READ_STRING(Location,Location); if ( key == "TimeZone" ) { utc = ( !value.isEmpty() ); } if ( state == When ) { if ( allday ) { item->PutAllDayEvent( true ); READ_DATE(StartDate,Start); // We can't just read the end date because Outlook does it differently to Qtopia. // Qtopia gives us something like "starts 7/10/08, ends 7/10/08" but Outlook // expects "starts 7/10/08 00:00:00, ends 8/10/08 00:00:00". // Simply add one day to the end date to get something Outlook won't barf over. if ( key == "EndDate" ) { QDate dt = stringToDate(value); QDateTime actual( dt.addDays(1), QTime(0,0,0) ); LOG() << "item->PutEnd" << actual; item->PutEnd( qdatetime_to_date(actual) ); } } else { item->PutAllDayEvent( false ); if ( key == "Start" ) { QDateTime dt = stringToDateTime(value, utc); if ( utc ) { dt.setTimeSpec( Qt::UTC ); dt = dt.toLocalTime(); } LOG() << "item->PutStart" << dt; item->PutStart( qdatetime_to_date(dt) ); } if ( key == "End" ) { QDateTime dt = stringToDateTime(value, utc); if ( utc ) { dt.setTimeSpec( Qt::UTC ); dt = dt.toLocalTime(); } LOG() << "item->PutEnd" << dt; item->PutEnd( qdatetime_to_date(dt) ); } } if ( key == "When" ) state = Idle; } if ( state == Alarm ) { READ_ENUM(Type,ReminderPlaySound,true,Audible); READ_ENUM(Type,ReminderPlaySound,false,Visible); READ_INT(Delay,ReminderMinutesBeforeStart); if ( key == "Alarm" ) state = Idle; } if ( dump_exception == false && state == Repeat ) { READ_ENUM_ITEM(Type,RecurrenceType,Outlook::olRecursDaily,Daily,recpat); READ_ENUM_ITEM(Type,RecurrenceType,Outlook::olRecursWeekly,Weekly,recpat); READ_ENUM_ITEM(Type,RecurrenceType,Outlook::olRecursMonthly,MonthlyDate,recpat); READ_ENUM_ITEM(Type,RecurrenceType,Outlook::olRecursMonthNth,MonthlyDay,recpat); READ_ENUM_ITEM(Type,RecurrenceType,Outlook::olRecursMonthNth,MonthlyEndDay,recpat); READ_ENUM_ITEM(Type,RecurrenceType,Outlook::olRecursYearly,Yearly,recpat); if ( key == "Type" ) { if ( value == "MonthlyEndDay" ) { LOG() << "recpat->PutInstance" << 5; recpat->PutInstance( 5 ); } } if ( key == "Frequency" ) { int interval = QVariant(value).toInt(); if ( interval >= 12 && interval % 12 == 0 ) { // since interval is bigger than 12 yet divisible by 12 this is more // likely to be a YearNth which Qtopia Sync Agent sends down as a // MonthNth with interval *= 12 recpat->PutRecurrenceType( Outlook::olRecursYearNth ); } LOG() << "recpat->PutInterval" << interval; recpat->PutInterval( interval ); } if ( key == "Until" ) { if ( value.isEmpty() ) { LOG() << "recpat->PutNoEndDate" << true; recpat->PutNoEndDate( true ); } else { LOG() << "recpat->PutPatternEndDate" << QDateTime( stringToDate(value), QTime(0,0,0) ); recpat->PutPatternEndDate( qdatetime_to_date(QDateTime( stringToDate(value), QTime(0,0,0) )) ); } } // Outlook doesn't seem to support Nearest == false (so ignore it) if ( key == "WeekMask" ) { int mask = 0; foreach( const QString &v, value.split(" ") ) { if ( v == "Monday" ) mask |= Outlook::olMonday; else if ( v == "Tuesday" ) mask |= Outlook::olTuesday; else if ( v == "Wednesday" ) mask |= Outlook::olWednesday; else if ( v == "Thursday" ) mask |= Outlook::olThursday; else if ( v == "Friday" ) mask |= Outlook::olFriday; else if ( v == "Saturday" ) mask |= Outlook::olSaturday; else if ( v == "Sunday" ) mask |= Outlook::olSunday; } LOG() << "recpat->PutDayOfWeekMask" << mask; recpat->PutDayOfWeekMask( (Outlook::OlDaysOfWeek)mask ); } if ( key == "Repeat" ) state = Idle; } if ( dump_exception == false && state == Exception ) { if ( key == "OriginalDate" ) { QDate exceptionDate = stringToDate(value); Outlook::_AppointmentItemPtr eitem = recpat->GetOccurrence( qdatetime_to_date(QDateTime( exceptionDate, QTime(0,0,0) )) ); QString entryid = read_item( eitem, reader, true ); if ( entryid.isEmpty() ) state = Repeat; // the delete case eats the closing Exception tag } if ( key == "Exception" ) { state = Repeat; } } READ_STRING(Notes,Body); if ( state == Categories ) { if ( key == "Category" ) categories << value; if ( key == "Categories" ) { LOG() << "item->PutCategories" << categories; item->PutCategories( qstring_to_bstr(categories.join(", ")) ); state = Idle; } } READ_CUSTOM(TimeZone,Qtopia Timezone); if ( dump_exception && key == "Appointment" ) loop = false; if ( dump_exception && key == "Exception" ) { // Oops... no Appointment tag in an Exception tag // That means we need to delete the existing exception item->Delete(); return QString(); } }
REIXSRIXSScanConfigurationView::REIXSRIXSScanConfigurationView(REIXSXESScanConfiguration* config, QWidget *parent) : AMScanConfigurationView(parent) { if(config) { configuration_ = config; ownsConfiguration_ = false; } else { configuration_ = new REIXSXESScanConfiguration(this); ownsConfiguration_ = true; } chooseScanDialog_ = 0; /* image_ = new MPlotSeriesBasic(); image_->setColorMap(*colorMap_); */ currentScan_ = 0; queueView_ = new AMActionRunnerQueueView3(AMActionRunner3::workflow()); detectorOptions = new QGroupBox("Initial Setup"); stopScanOptions = new QGroupBox("Stop scan when..."); nameOptions = new QGroupBox("Scan meta-data"); XASEnergySelect = new QGroupBox("Select Scan Energy"); energyBox_ = new QDoubleSpinBox(); energyBox_->setDecimals(2); energyBox_->setEnabled(true); energyBox_->setRange(92,2000); energyBox_->setValue(configuration_->energy()); energyBox_->setSingleStep(0.1); energyBoxLabel_ = new QLabel("RIXS Excitation Energy:"); slitWidthBox_= new QDoubleSpinBox(); slitWidthBox_->setRange(5,500); slitWidthBox_->setValue(configuration_->slitWidth()); slitWidthBox_->setSingleStep(5); slitWidthBox_->setDecimals(0); slitWidthBox_->setEnabled(configuration_->applySlitWidth()); applySlitWidthBox_ = new QCheckBox("Slit Width"); applySlitWidthBox_->setChecked(configuration_->applySlitWidth()); polarizationBox_ = new QComboBox(); polarizationBox_->addItem("Circular Left"); polarizationBox_->addItem("Circular Right"); polarizationBox_->addItem("Linear Horizontal"); polarizationBox_->addItem("Linear Vertical +"); polarizationBox_->addItem("Linear Vertical -"); polarizationBox_->addItem("Linear Inclined"); polarizationBox_->setCurrentIndex(configuration_->polarization()); polarizationBox_->setEnabled(configuration_->applyPolarization()); applyPolarizationBox_ = new QCheckBox("Polarization"); applyPolarizationBox_->setChecked(configuration_->applyPolarization()); polarizationAngleBox_ = new QDoubleSpinBox(); polarizationAngleBox_->setDecimals(0); polarizationAngleBox_->setRange(-180,180); polarizationAngleBox_->setEnabled((configuration_->applyPolarization() && (configuration_->polarization() == 5))); polarizationAngleBox_->setValue(configuration_->polarizationAngle()); polarizationAngleBox_->setSingleStep(10); polarizationAngleLabel_ = new QLabel(); polarizationAngleLabel_->setText(" Angle"); doNotClearExistingCountsOption_ = new QCheckBox("Do not clear previous detector data"); maximumTotalCounts_ = new QDoubleSpinBox(); maximumTimeEdit_ = new QTimeEdit(); numberEdit_ = new QSpinBox(); numberEdit_->setRange(0, 10000); numberEdit_->setEnabled(false); nameEdit_ = new QLineEdit(); sampleSelector_ = new AMSamplePre2013Editor(AMDatabase::database("user")); autoNamingCheckBox_ = new QCheckBox("from last sample move"); maximumTotalCounts_->setDecimals(0); maximumTotalCounts_->setRange(10, 1000000000); maximumTimeEdit_->setDisplayFormat("hh:mm:ss"); XASScanName_ = new QLabel("Select XAS Scan..."); /* addEnergy_ = new QPushButton(); addEnergy_->setText("Add Energy"); QIcon down; down.addFile(QString::fromUtf8(":/22x22/go-down-dark.png"), QSize(), QIcon::Normal, QIcon::Off); addEnergy_->setIcon(down); queueScan_ = new QPushButton(); queueScan_->setText("Add This Energy"); */ loadXASData_ = new QPushButton(); loadXASData_->setText("Load XAS Scan"); // Add scan view (plots) scanView_ = new AMScanView(); scanView_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); scanView_->changeViewMode(AMScanView::Tabs); // share the scan set model with the AMScanView scanSetModel_ = scanView_->model(); /* plot_ = new MPlot(); plotWidget_ = new MPlotWidget(); plotWidget_->setPlot(plot_); plot_->plotArea()->setBrush(QBrush(QColor(Qt::white))); plot_->axisRight()->setTicks(0); plot_->axisBottom()->setTicks(4); plot_->axisLeft()->showGrid(false); plot_->axisBottom()->showAxisName(false); plot_->axisLeft()->showAxisName(false); plot_->axisScaleBottom()->setPadding(0); plot_->axisScaleLeft()->setPadding(0); image_ = 0; */ QGridLayout* RIXSView = new QGridLayout(); QGridLayout* initialSetupLayout = new QGridLayout(); initialSetupLayout->addWidget(applySlitWidthBox_,1,0); initialSetupLayout->addWidget(slitWidthBox_,1,1); initialSetupLayout->addWidget(applyPolarizationBox_,2,0); initialSetupLayout->addWidget(polarizationBox_,2,1); initialSetupLayout->addWidget(polarizationAngleLabel_,3,0); initialSetupLayout->addWidget(polarizationAngleBox_,3,1); initialSetupLayout->addWidget(doNotClearExistingCountsOption_,4,0,1,2,0); detectorOptions->setLayout(initialSetupLayout); QFormLayout* stopScanWhenLayout = new QFormLayout(); stopScanWhenLayout->addRow("Total Counts Reaches", maximumTotalCounts_); stopScanWhenLayout->addRow("After this much time", maximumTimeEdit_); stopScanOptions->setLayout(stopScanWhenLayout); QFormLayout* scanMetaDataLayout = new QFormLayout(); scanMetaDataLayout->addRow("Scan base name", nameEdit_); /* scanMetaDataLayout->addRow("Number", numberEdit_); */ scanMetaDataLayout->addRow("Sample", sampleSelector_); scanMetaDataLayout->addRow("Set automatically", autoNamingCheckBox_); nameOptions->setLayout(scanMetaDataLayout); QGridLayout* XASScanViewLayout = new QGridLayout(); XASScanViewLayout->addWidget(scanView_,0,0,1,5); XASScanViewLayout->addWidget(energyBoxLabel_,1,0); XASScanViewLayout->addWidget(energyBox_,1,1); /* XASScanViewLayout->addWidget(queueScan_,1,2); */ XASScanViewLayout->addWidget(loadXASData_,1,4); XASEnergySelect->setLayout(XASScanViewLayout); RIXSView->addWidget(detectorOptions, 0,0); RIXSView->addWidget(stopScanOptions,1,0); RIXSView->addWidget(nameOptions,2,0); RIXSView->addWidget(XASEnergySelect,0,1,3,1); RIXSView->addWidget(queueView_, 3,0,1,2); QVBoxLayout* outerVLayout = new QVBoxLayout(); outerVLayout->setContentsMargins(0,0,0,0); outerVLayout->setSpacing(0); outerVLayout->addWidget(new AMTopFrame("Setup RIXS Scans", QIcon(":/utilities-system-monitor.png"))); outerVLayout->addLayout(RIXSView); setLayout(outerVLayout); currentCalibrationId_ = -1; maximumTotalCounts_->setValue(configuration_->maximumTotalCounts()); maximumTimeEdit_->setTime(QTime().addSecs(int(configuration_->maximumDurationSeconds()))); doNotClearExistingCountsOption_->setChecked(configuration_->doNotClearExistingCounts()); nameEdit_->setText(configuration_->userScanName()); numberEdit_->setValue(configuration_->scanNumber()); sampleSelector_->setCurrentSampleFromId(configuration_->sampleId()); autoNamingCheckBox_->setChecked(configuration_->namedAutomatically()); onAutoNamingCheckboxClicked(configuration_->namedAutomatically()); configuration_->setApplyEnergy(true); connect(loadXASData_, SIGNAL(clicked()), this, SLOT(onloadXASDataClicked())); /* connect(queueScan_, SIGNAL(clicked()), this, SLOT(onQueueScanClicked())); */ connect(applySlitWidthBox_, SIGNAL(toggled(bool)),slitWidthBox_,SLOT(setEnabled(bool))); connect(applySlitWidthBox_, SIGNAL(clicked(bool)), configuration_, SLOT(setApplySlitWidth(bool))); connect(slitWidthBox_, SIGNAL(valueChanged(double)), configuration_, SLOT(setSlitWidth(double))); connect(energyBox_, SIGNAL(valueChanged(double)), configuration_, SLOT(setEnergy(double))); connect(applyPolarizationBox_, SIGNAL(clicked(bool)), configuration_, SLOT(setApplyPolarization(bool))); connect(polarizationBox_, SIGNAL(currentIndexChanged(int)), configuration_, SLOT(setPolarization(int))); connect(polarizationAngleBox_, SIGNAL(valueChanged(double)), configuration_, SLOT(setPolarizationAngle(double))); connect(applyPolarizationBox_, SIGNAL(clicked(bool)), polarizationBox_, SLOT(setEnabled(bool))); connect(applyPolarizationBox_, SIGNAL(clicked(bool)), this, SLOT(reviewPolarizationAngleBoxEnabled())); connect(polarizationBox_, SIGNAL(activated(int)), this, SLOT(reviewPolarizationAngleBoxEnabled())); connect(doNotClearExistingCountsOption_, SIGNAL(toggled(bool)), configuration_, SLOT(setDoNotClearExistingCounts(bool))); connect(maximumTotalCounts_, SIGNAL(valueChanged(double)), configuration_, SLOT(setMaximumTotalCounts(double))); connect(maximumTimeEdit_, SIGNAL(timeChanged(QTime)), this, SLOT(onMaximumTimeEditChanged(QTime))); connect(autoNamingCheckBox_, SIGNAL(clicked(bool)), this, SLOT(onAutoNamingCheckboxClicked(bool))); connect(nameEdit_, SIGNAL(textEdited(QString)), configuration_, SLOT(setUserScanName(QString))); connect(numberEdit_, SIGNAL(valueChanged(int)), configuration_, SLOT(setScanNumber(int))); connect(sampleSelector_, SIGNAL(currentSampleChanged(int)), configuration_, SLOT(setSampleId(int))); connect(autoNamingCheckBox_, SIGNAL(clicked(bool)), configuration_, SLOT(setNamedAutomatically(bool))); connect(scanView_, SIGNAL(dataPositionChanged(QPointF)), this, SLOT(onDataPositionToolChanged(QPointF))); connect(energyBox_, SIGNAL(valueChanged(double)), this, SLOT(onEnergySpinBoxChanged(double))); }
QTime TimeBar::getTime() { QTime time = QTime(); time.setHMS(ms / (1000*60*60), (ms % (1000*60*60)) / (1000*60), ((ms % (1000*60*60)) % (1000*60)) / 1000); return time; }
QVariant Device::data(const QModelIndex &index, int role) const { log_entry entry; QTime mstime; int div = 1; Q_ASSERT(index.row() < m_log.size()); switch (role) { case Qt::EditRole: switch ( index.column() ) { case Device::REGISTER: entry = m_log.read( index.row() ); return get_register_name(entry) + QString().sprintf(" 0x%08X", entry.offset + (m_base >= 0x50000000 ? m_base : 0)); default: break; } case Qt::DisplayRole: entry = m_log.read( index.row() ); switch ( index.column() ) { case Device::REGISTER: if (entry.is_irq) return QString("IRQ ") + QString::number(entry.offset); if (entry.is_error) { const char *format = entry.is_write ? "write%d to 0x%X" : "read%d 0x%X"; return QString().sprintf(format, entry.rw_size, entry.offset); } if (entry.clk_disabled || entry.in_reset) return get_register_name(entry) + " clk_enb: " + QString::number(!entry.clk_disabled) + " rst: " + QString::number(entry.in_reset); return get_register_name(entry); case Device::VALUE: if (entry.is_irq) return QString("STATUS ") + QString::number(entry.value); return QString().sprintf("0x%08X", entry.is_write? entry.new_value : entry.value); case Device::TIME: mstime = QTime(0, 0).addMSecs(entry.time / 1000); return mstime.toString("hh:mm:ss.zzz") + QString().sprintf(".%03d", entry.time % 1000); case Device::CPU_PC: return QString().sprintf("[%d] @0x%08X", entry.cpu_id, entry.cpu_pc); default: break; } break; case Qt::BackgroundRole: entry = m_log.read( index.row() ); if (m_regFilter.length() && get_register_name(entry).indexOf(m_regFilter) == -1) div = 2; if (index.column() == Device::CPU_PC) return QVariant(); if (entry.is_irq) { if (entry.value) return QColor(255 / div, 192 / div, 255 / div); else return QColor(192 / div, 255 / div, 255 / div); } if (entry.is_error) return QColor(255 / div, 150 / div, 150 / div); // light red if (index.column() == Device::REGISTER) { if (entry.clk_disabled || entry.in_reset) return QColor(255 / div, 150 / div, 150 / div); // light red } if (!entry.is_write) return QColor(200 / div, 255 / div, 200 / div); // light green if (entry.value != entry.new_value) return QColor(0xf4 / div, 0xa7 / div, 0); // brown return QColor(255 / div, 255 / div, 150 / div); // light yellow case Qt::ToolTipRole: switch ( index.column() ) { case Device::TIME: entry = m_log.read( index.row() ); return QString::number(entry.time) + "us"; case Device::REGISTER: entry = m_log.read( index.row() ); return QString().sprintf("0x%08X", entry.offset); default: break; } break; case Qt::ForegroundRole: if (index.column() != Device::CPU_PC) return QColor(Qt::black); break; default: break; } return QVariant(); }
void XMMSSensor::update() { QString format; SensorParams *sp; Meter *meter; QObjectListIt it( *objList ); #ifdef HAVE_XMMS int pos; QString title; int songLength = 0; int currentTime = 0; bool isPlaying = false; bool isRunning = xmms_remote_is_running(0); if( isRunning ) { isPlaying = xmms_remote_is_playing(0); pos = xmms_remote_get_playlist_pos(0); qDebug("unicode start"); title = codec->toUnicode( QCString( xmms_remote_get_playlist_title( 0, pos ) ) ); qDebug("unicode end"); if( title.isEmpty() ) title = "XMMS"; qDebug("Title: %s", title.ascii()); songLength = xmms_remote_get_playlist_time( 0, pos ); currentTime = xmms_remote_get_output_time( 0 ); } #endif // HAVE_XMMS while (it != 0) { sp = (SensorParams*)(*it); meter = sp->getMeter(); #ifdef HAVE_XMMS if( isRunning ) { format = sp->getParam("FORMAT"); if (format.length() == 0 ) { format = "%title %time / %length"; } if( format == "%ms" ) { meter->setMax( songLength ); meter->setValue( currentTime ); } else if ( format == "%full" ) { meter->setValue( 1 ); } else { format.replace( QRegExp("%title", false), title ); format.replace( QRegExp("%length", false), QTime( 0,0,0 ). addMSecs( songLength ) .toString( "h:mm:ss" ) ); format.replace( QRegExp("%time", false), QTime( 0,0,0 ). addMSecs( currentTime ) .toString( "h:mm:ss" ) ); if( isPlaying ) { format.replace( QRegExp("%remain", false), QTime( 0,0,0 ). addMSecs( songLength ) .addMSecs(-currentTime ) .toString( "h:mm:ss" ) ); } else { format.replace( QRegExp("%remain", false), QTime( 0,0,0 ).toString("h:mm:ss" ) ); } meter->setValue(format); } } else #endif // HAVE_XMMS { meter->setValue(""); } ++it; } }
void Groupwise::getFreeBusy(const KURL &url) { QString file = url.filename(); if(file.right(4) != ".ifb") { QString error = i18n("Illegal filename. File has to have '.ifb' suffix."); errorMessage(error); } else { QString email = file.left(file.length() - 4); debugMessage("Email: " + email); // Sanitise local Nuernberg email addresses kdDebug() << "Email before sanitizing: " << email << endl; email = email.replace(QRegExp("\\.EMEA5-1\\.EMEA5"), ""); email = email.replace(QRegExp("\\.Suse.INTERNET"), ""); kdDebug() << "Email after sanitizing: " << email << endl; QString u = soapUrl(url); QString user = url.user(); QString pass = url.pass(); debugMessage("URL: " + u); debugMessage("User: "******"Password: "******"Need username and password to read Free/Busy information.")); } else { GroupwiseServer server(u, user, pass, 0); // FIXME: Read range from configuration or URL parameters. QDate start = QDate::currentDate().addDays(-3); QDate end = QDate::currentDate().addDays(60); fb->setDtStart(start); fb->setDtEnd(end); kdDebug() << "Login" << endl; if(!server.login()) { errorMessage(i18n("Unable to login: "******"Read free/busy" << endl; if(!server.readFreeBusy(email, start, end, fb)) { errorMessage(i18n("Unable to read free/busy data: ") + server.errorText()); } kdDebug() << "Read free/busy" << endl; server.logout(); } } #if 0 QDateTime s = QDateTime(QDate(2004, 9, 27), QTime(10, 0)); QDateTime e = QDateTime(QDate(2004, 9, 27), QTime(11, 0)); fb->addPeriod(s, e); #endif // FIXME: This does not take into account the time zone! KCal::ICalFormat format; QString ical = format.createScheduleMessage(fb, KCal::Scheduler::Publish); data(ical.utf8()); finished(); } }
QTime::isValid(21, 10, 30); // returns true QTime::isValid(22, 5, 62); // returns false //! [9] //! [10] QTime t; t.start(); some_lengthy_task(); qDebug("Time elapsed: %d ms", t.elapsed()); //! [10] //! [11] QDateTime now = QDateTime::currentDateTime(); QDateTime xmas(QDate(now.date().year(), 12, 25), QTime(0, 0)); qDebug("There are %d seconds to Christmas", now.secsTo(xmas)); //! [11] //! [12] QTime time1 = QTime::fromString("131", "HHh"); // time1 is 13:00:00 QTime time1 = QTime::fromString("1apA", "1amAM"); // time1 is 01:00:00 QDateTime dateTime2 = QDateTime::fromString("M1d1y9800:01:02", "'M'M'd'd'y'yyhh:mm:ss"); // dateTime is 1 January 1998 00:01:02 //! [12]
/* Function used for finding the old backup directories to remove. Kaveau keeps: - hourly backups for the past 24 hours - daily backups for the past month - weekly backups until the external disk is full */ void TestCommon::testFindBackupDirectoriesToDelete_data() { QTest::addColumn<QStringList>( "dirs" ); QTest::addColumn<QStringList>( "expected" ); QStringList input; QStringList output; QDateTime now = QDateTime::currentDateTime(); QDateTime dateTime; // empty lists input.clear(); output.clear(); QTest::newRow("emtpy list") << input << output; // 24h backups input.clear(); output.clear(); dateTime = now; dateTime.setTime(QTime(now.time().hour(), 10, 00)); for (int i = 0; i < 5; i++) { QDateTime time_to_keep = dateTime.addSecs(-i*3600); // i hour(s) ago QDateTime time_to_delete = time_to_keep.addSecs(-60); // i hour(s) and 1m ago input << time_to_keep.toString(DATE_FORMAT); input << time_to_delete.toString(DATE_FORMAT); output << time_to_delete.toString(DATE_FORMAT); } QTest::newRow("last 24 hours backups") << input << output; // last month backups dateTime = now; dateTime.setTime(QTime(now.time().hour(), 10, 00)); for (int i = 2; i < 5; i++) { QDateTime time_to_keep = dateTime.addDays(-i); // i days ago QDateTime time_to_delete = time_to_keep.addSecs(-60); // i day(s) and 1m ago input << time_to_keep.toString(DATE_FORMAT); input << time_to_delete.toString(DATE_FORMAT); output << time_to_delete.toString(DATE_FORMAT); } QTest::newRow("last 24 hours + last month backups") << input << output; // weekly backups dateTime = now; dateTime.setTime(QTime(now.time().hour(), 10, 00)); dateTime = dateTime.addMonths(-2); // 2 months ago for (int i = 1; i < 5; i++) { QDateTime time_to_keep = dateTime.addDays(-i*7); // i week(s) ago QDateTime time_to_delete = time_to_keep.addSecs(-60); // i week(s) and 1m ago input << time_to_keep.toString(DATE_FORMAT); input << time_to_delete.toString(DATE_FORMAT); output << time_to_delete.toString(DATE_FORMAT); } QTest::newRow("last 24 hours + last month + some weeks backups") << input << output; // nothing to delete input.clear(); output.clear(); dateTime = now; dateTime.setTime(QTime(now.time().hour(), 10, 00)); for (int i = 0; i < 5; i++) { QDateTime time_to_keep = dateTime.addSecs(-i*3600); // i hour(s) ago input << time_to_keep.toString(DATE_FORMAT); } for (int i = 2; i < 5; i++) { QDateTime time_to_keep = dateTime.addDays(-i); // i days ago input << time_to_keep.toString(DATE_FORMAT); } for (int i = 1; i < 5; i++) { QDateTime time_to_keep = dateTime.addDays(-i*7); // i week(s) ago input << time_to_keep.toString(DATE_FORMAT); } QTest::newRow("nothing to delete") << input << output; }
void AddresseeTest::storeTest() { KContacts::Addressee addressee; KContacts::Picture logo(QStringLiteral("http://scottlandyard.info/pics/logo.png")); KContacts::Picture photo(QStringLiteral("http://scottlandyard.info/~sinclair/photo.png")); KContacts::Sound sound(QStringLiteral("http://scottlandyard.info/~sinclair/sound.wav")); QStringList emails; emails << QStringLiteral("*****@*****.**") << QStringLiteral("*****@*****.**"); KContacts::Key::List keys; keys << KContacts::Key(QStringLiteral("SecretKey")); QStringList categories; categories << QStringLiteral("Helper") << QStringLiteral("Friend"); QStringList customs; customs << QStringLiteral("X-Danger: high"); KContacts::Gender gender(QStringLiteral("H")); addressee.setGender(gender); KContacts::Lang lang(QLatin1String("lang")); addressee.setLangs(KContacts::Lang::List() << lang); addressee.setUid(QStringLiteral("My uid")); addressee.setName(QStringLiteral("John Sinclair")); addressee.setFormattedName(QStringLiteral("Sinclair, John")); addressee.setFamilyName(QStringLiteral("Sinclair")); addressee.setGivenName(QStringLiteral("John")); addressee.setAdditionalName(QStringLiteral("Bob")); addressee.setPrefix(QStringLiteral("Sir")); addressee.setSuffix(QStringLiteral("II")); addressee.setNickName(QStringLiteral("ghosthunter")); addressee.setBirthday(QDate(1982, 7, 19)); addressee.setMailer(QStringLiteral("mutt")); addressee.setTimeZone(KContacts::TimeZone(2)); addressee.setGeo(KContacts::Geo(42, 23)); addressee.setTitle(QStringLiteral("Ghost Hunter")); addressee.setRole(QStringLiteral("Leader")); addressee.setOrganization(QStringLiteral("Scottland Yard")); addressee.setNote(QStringLiteral("Don't cross black deads way...")); addressee.setProductId(QStringLiteral("ProductId45")); addressee.setRevision(QDateTime(QDate(1982, 9, 15))); addressee.setSortString(QStringLiteral("Name")); KContacts::ResourceLocatorUrl url; url.setUrl(QUrl(QStringLiteral("www.scottlandyard.info"))); addressee.setUrl(url); addressee.setSecrecy(KContacts::Secrecy(KContacts::Secrecy::Public)); addressee.setLogo(logo); addressee.setPhoto(photo); addressee.setSound(sound); addressee.setEmails(emails); addressee.setKeys(keys); addressee.setCategories(categories); addressee.setCustoms(customs); addressee.setKind(QStringLiteral("foo")); addressee.setChanged(false); KContacts::Impp imp; imp.setType(KContacts::Impp::GaduGadu); imp.setAddress(QStringLiteral("*****@*****.**")); KContacts::Impp::List listImp; listImp << imp; addressee.setImppList(listImp); QVERIFY(addressee.imppList() == listImp); QVERIFY(addressee.langs() == (KContacts::Lang::List() << lang)); QVERIFY(addressee.gender() == gender); QVERIFY(addressee.uid() == QStringLiteral("My uid")); QVERIFY(addressee.name() == QStringLiteral("John Sinclair")); QVERIFY(addressee.formattedName() == QStringLiteral("Sinclair, John")); QVERIFY(addressee.familyName() == QStringLiteral("Sinclair")); QVERIFY(addressee.givenName() == QStringLiteral("John")); QVERIFY(addressee.additionalName() == QStringLiteral("Bob")); QVERIFY(addressee.prefix() == QStringLiteral("Sir")); QVERIFY(addressee.suffix() == QStringLiteral("II")); QVERIFY(addressee.nickName() == QStringLiteral("ghosthunter")); QVERIFY(addressee.birthday().date() == QDate(1982, 7, 19)); QVERIFY(addressee.birthday().time() == QTime(0, 0)); QVERIFY(!addressee.birthdayHasTime()); QVERIFY(addressee.mailer() == QStringLiteral("mutt")); QVERIFY(addressee.timeZone() == KContacts::TimeZone(2)); QVERIFY(addressee.geo() == KContacts::Geo(42, 23)); QVERIFY(addressee.title() == QStringLiteral("Ghost Hunter")); QVERIFY(addressee.role() == QStringLiteral("Leader")); QVERIFY(addressee.organization() == QStringLiteral("Scottland Yard")); QVERIFY(addressee.note() == QStringLiteral("Don't cross black deads way...")); QVERIFY(addressee.productId() == QStringLiteral("ProductId45")); QVERIFY(addressee.revision() == QDateTime(QDate(1982, 9, 15))); QVERIFY(addressee.sortString() == QStringLiteral("Name")); QVERIFY(addressee.url() == url); QVERIFY(addressee.secrecy() == KContacts::Secrecy(KContacts::Secrecy::Public)); QVERIFY(addressee.logo() == logo); QVERIFY(addressee.photo() == photo); QVERIFY(addressee.sound() == sound); QVERIFY(addressee.emails() == emails); QVERIFY(addressee.keys() == keys); QVERIFY(addressee.categories() == categories); QVERIFY(addressee.customs() == customs); QVERIFY(addressee.changed() == false); QCOMPARE(addressee.kind(), QStringLiteral("foo")); }
/* Parse all the date formats that Firefox can. The official format is: expires=ddd(d)?, dd-MMM-yyyy hh:mm:ss GMT But browsers have been supporting a very wide range of date strings. To work on many sites we need to support more then just the official date format. For reference see Firefox's PR_ParseTimeStringToExplodedTime in prtime.c. The Firefox date parser is coded in a very complex way and is slightly over ~700 lines long. While this implementation will be slightly slower for the non standard dates it is smaller, more readable, and maintainable. Or in their own words: "} // else what the hell is this." */ static QDateTime parseDateString(const QByteArray &dateString) { QTime time; // placeholders for values when we are not sure it is a year, month or day int unknown[3] = {-1, -1, -1}; int month = -1; int day = -1; int year = -1; int zoneOffset = -1; // hour:minute:second.ms pm QRegExp timeRx(QLatin1String("(\\d{1,2}):(\\d{1,2})(:(\\d{1,2})|)(\\.(\\d{1,3})|)((\\s{0,}(am|pm))|)")); int at = 0; while (at < dateString.length()) { #ifdef PARSEDATESTRINGDEBUG qDebug() << dateString.mid(at); #endif bool isNum = isNumber(dateString[at]); // Month if (!isNum && checkStaticArray(month, dateString, at, months, sizeof(months)- 1)) { ++month; #ifdef PARSEDATESTRINGDEBUG qDebug() << "Month:" << month; #endif at += 3; continue; } // Zone if (!isNum && zoneOffset == -1 && checkStaticArray(zoneOffset, dateString, at, zones, sizeof(zones)- 1)) { int sign = (at >= 0 && dateString[at - 1] == '-') ? -1 : 1; zoneOffset = sign * zoneOffsets[zoneOffset] * 60 * 60; #ifdef PARSEDATESTRINGDEBUG qDebug() << "Zone:" << month; #endif at += 3; continue; } // Zone offset if (!isNum && (zoneOffset == -1 || zoneOffset == 0) // Can only go after gmt && (dateString[at] == '+' || dateString[at] == '-') && (at == 0 || isWhitespace(dateString[at - 1]) || dateString[at - 1] == ',' || (at >= 3 && (dateString[at - 3] == 'g') && (dateString[at - 2] == 'm') && (dateString[at - 1] == 't')))) { int end = 1; while (end < 5 && dateString.length() > at+end && dateString[at + end] >= '0' && dateString[at + end] <= '9') ++end; int minutes = 0; int hours = 0; switch (end - 1) { case 4: minutes = atoi(dateString.mid(at + 3, 2).constData()); // fall through case 2: hours = atoi(dateString.mid(at + 1, 2).constData()); break; case 1: hours = atoi(dateString.mid(at + 1, 1).constData()); break; default: at += end; continue; } if (end != 1) { int sign = dateString[at] == '-' ? -1 : 1; zoneOffset = sign * ((minutes * 60) + (hours * 60 * 60)); #ifdef PARSEDATESTRINGDEBUG qDebug() << "Zone offset:" << zoneOffset << hours << minutes; #endif at += end; continue; } } // Time if (isNum && time.isNull() && dateString.length() >= at + 3 && (dateString[at + 2] == ':' || dateString[at + 1] == ':')) { // While the date can be found all over the string the format // for the time is set and a nice regexp can be used. int pos = timeRx.indexIn(QLatin1String(dateString), at); if (pos != -1) { QStringList list = timeRx.capturedTexts(); int h = atoi(list.at(1).toLatin1().constData()); int m = atoi(list.at(2).toLatin1().constData()); int s = atoi(list.at(4).toLatin1().constData()); int ms = atoi(list.at(6).toLatin1().constData()); if (h < 12 && !list.at(9).isEmpty()) if (list.at(9) == QLatin1String("pm")) h += 12; time = QTime(h, m, s, ms); #ifdef PARSEDATESTRINGDEBUG qDebug() << "Time:" << list << timeRx.matchedLength(); #endif at += timeRx.matchedLength(); continue; } } // 4 digit Year if (isNum && year == -1 && dateString.length() >= at + 3) { if (isNumber(dateString[at + 1]) && isNumber(dateString[at + 2]) && isNumber(dateString[at + 3])) { year = atoi(dateString.mid(at, 4).constData()); at += 4; #ifdef PARSEDATESTRINGDEBUG qDebug() << "Year:" << year; #endif continue; } } // a one or two digit number // Could be month, day or year if (isNum) { int length = 1; if (dateString.length() > at + 1 && isNumber(dateString[at + 1])) ++length; int x = atoi(dateString.mid(at, length).constData()); if (year == -1 && (x > 31 || x == 0)) { year = x; } else { if (unknown[0] == -1) unknown[0] = x; else if (unknown[1] == -1) unknown[1] = x; else if (unknown[2] == -1) unknown[2] = x; } at += length; #ifdef PARSEDATESTRINGDEBUG qDebug() << "Saving" << x; #endif continue; } // Unknown character, typically a weekday such as 'Mon' ++at; } // Once we are done parsing the string take the digits in unknown // and determine which is the unknown year/month/day int couldBe[3] = { 0, 0, 0 }; int unknownCount = 3; for (int i = 0; i < unknownCount; ++i) { if (unknown[i] == -1) { couldBe[i] = ADAY | AYEAR | AMONTH; unknownCount = i; continue; } if (unknown[i] >= 1) couldBe[i] = ADAY; if (month == -1 && unknown[i] >= 1 && unknown[i] <= 12) couldBe[i] |= AMONTH; if (year == -1) couldBe[i] |= AYEAR; } // For any possible day make sure one of the values that could be a month // can contain that day. // For any possible month make sure one of the values that can be a // day that month can have. // Example: 31 11 06 // 31 can't be a day because 11 and 6 don't have 31 days for (int i = 0; i < unknownCount; ++i) { int currentValue = unknown[i]; bool findMatchingMonth = couldBe[i] & ADAY && currentValue >= 29; bool findMatchingDay = couldBe[i] & AMONTH; if (!findMatchingMonth || !findMatchingDay) continue; for (int j = 0; j < 3; ++j) { if (j == i) continue; for (int k = 0; k < 2; ++k) { if (k == 0 && !(findMatchingMonth && (couldBe[j] & AMONTH))) continue; else if (k == 1 && !(findMatchingDay && (couldBe[j] & ADAY))) continue; int m = currentValue; int d = unknown[j]; if (k == 0) qSwap(m, d); if (m == -1) m = month; bool found = true; switch(m) { case 2: // When we get 29 and the year ends up having only 28 // See date.isValid below // Example: 29 23 Feb if (d <= 29) found = false; break; case 4: case 6: case 9: case 11: if (d <= 30) found = false; break; default: if (d > 0 && d <= 31) found = false; } if (k == 0) findMatchingMonth = found; else if (k == 1) findMatchingDay = found; } } if (findMatchingMonth) couldBe[i] &= ~ADAY; if (findMatchingDay) couldBe[i] &= ~AMONTH; } // First set the year/month/day that have been deduced // and reduce the set as we go along to deduce more for (int i = 0; i < unknownCount; ++i) { int unset = 0; for (int j = 0; j < 3; ++j) { if (couldBe[j] == ADAY && day == -1) { day = unknown[j]; unset |= ADAY; } else if (couldBe[j] == AMONTH && month == -1) { month = unknown[j]; unset |= AMONTH; } else if (couldBe[j] == AYEAR && year == -1) { year = unknown[j]; unset |= AYEAR; } else { // common case break; } couldBe[j] &= ~unset; } } // Now fallback to a standardized order to fill in the rest with for (int i = 0; i < unknownCount; ++i) { if (couldBe[i] & AMONTH && month == -1) month = unknown[i]; else if (couldBe[i] & ADAY && day == -1) day = unknown[i]; else if (couldBe[i] & AYEAR && year == -1) year = unknown[i]; } #ifdef PARSEDATESTRINGDEBUG qDebug() << "Final set" << year << month << day; #endif if (year == -1 || month == -1 || day == -1) { #ifdef PARSEDATESTRINGDEBUG qDebug() << "Parser failure" << year << month << day; #endif return QDateTime(); } // Y2k behavior int y2k = 0; if (year < 70) y2k = 2000; else if (year < 100) y2k = 1900; QDate date(year + y2k, month, day); // When we were given a bad cookie that when parsed // set the day to 29 and the year to one that doesn't // have the 29th of Feb rather then adding the extra // complicated checking earlier just swap here. // Example: 29 23 Feb if (!date.isValid()) date = QDate(day + y2k, month, year); QDateTime dateTime(date, time, Qt::UTC); if (zoneOffset != -1) { dateTime = dateTime.addSecs(zoneOffset); } if (!dateTime.isValid()) return QDateTime(); return dateTime; }
void FunctionsTest::testDateTimeFromString() { // Timestamps QCOMPARE(qDateTimeFromString("1492192180").toUTC(), QDateTime(QDate(2017, 4, 14), QTime(17, 49, 40), Qt::UTC)); // Standart dates QCOMPARE(qDateTimeFromString("2017/04/14 17:49:40").toUTC(), QDateTime(QDate(2017, 4, 14), QTime(17, 49, 40), Qt::UTC)); QCOMPARE(qDateTimeFromString("2017-04-14 17:49:40").toUTC(), QDateTime(QDate(2017, 4, 14), QTime(17, 49, 40), Qt::UTC)); QCOMPARE(qDateTimeFromString("2017/04/14 17:49").toUTC(), QDateTime(QDate(2017, 4, 14), QTime(17, 49), Qt::UTC)); QCOMPARE(qDateTimeFromString("2017-04-14 17:49").toUTC(), QDateTime(QDate(2017, 4, 14), QTime(17, 49), Qt::UTC)); // Danbooru dates QCOMPARE(qDateTimeFromString("2017-04-14T17:49:40.498-04:00").toUTC(), QDateTime(QDate(2017, 4, 14), QTime(17 + 4, 49, 40), Qt::UTC)); // Gelbooru dates QCOMPARE(qDateTimeFromString("Tue Apr 4 17:49:40 2017").toUTC(), QDateTime(QDate(2017, 4, 4), QTime(17, 49, 40), Qt::UTC)); QCOMPARE(qDateTimeFromString("Fri Apr 14 17:49:40 2017").toUTC(), QDateTime(QDate(2017, 4, 14), QTime(17, 49, 40), Qt::UTC)); QCOMPARE(qDateTimeFromString("Fri Apr 14 17:49:40 -0500 2017").toUTC(), QDateTime(QDate(2017, 4, 14), QTime(17 + 5, 49, 40), Qt::UTC)); QCOMPARE(qDateTimeFromString("Fri Apr 14 23:49:40 -0500 2017").toUTC(), QDateTime(QDate(2017, 4, 15), QTime(4, 49, 40), Qt::UTC)); }
bool kfile_metadatPlugin::readInfo ( KFileMetaInfo& info, uint what ) { bool readTech = false; // add your "calculations" here // if something goes wrong, "return false;" if ( what & ( KFileMetaInfo::Fastest | KFileMetaInfo::DontCare | KFileMetaInfo::TechnicalInfo ) ) readTech = true; if ( info.path().isEmpty() ) // remote file cannot be handled return false; if ( readTech ) { KFileMetaInfoGroup group = appendGroup ( info, "Technical" ); char buffer[112]; QFile qf ( info.path() ); if ( ! qf.open ( IO_ReadOnly ) || ( qf.readBlock ( buffer, 112 ) != 112 ) ) return false; // File cannot be read --> no meta info qf.close(); try { comag::meta m ( ( const unsigned char * ) buffer ); appendItem ( group, "Title", QString::fromLatin1( m.gettitle().data() ) ); appendItem ( group, "Title Type", ( m.gettitle_type() == comag::meta::TT_TRANSMISSION ) ? i18n ( "Transmission" ) : ( m.gettitle_type() == comag::meta::TT_STATION ) ? i18n ( "Station" ) : i18n ( "Unknown" ) ); #ifdef ENABLE_DATETIMETWOLINES appendItem ( group, "Start Time", QTime ( m.getstart_time().hour, m.getstart_time().minute, m.getstart_time().second ) ); appendItem ( group, "Start Date", QDate ( m.getstart_date().year, m.getstart_date().month, m.getstart_date().day ) ); #else appendItem ( group, "Start Time", QDateTime ( QDate ( m.getstart_date().year, m.getstart_date().month, m.getstart_date().day ), QTime ( m.getstart_time().hour, m.getstart_time().minute, m.getstart_time().second ) ) ); #endif appendItem ( group, "Duration", QTime ( m.getduration().hour, m.getduration().minute, m.getduration().second ) ); appendItem ( group, "Packets", m.getpackets() ); appendItem ( group, "Service", ( m.getservice() == comag::meta::S_RADIO ) ? i18n ( "Radio" ) : ( m.getservice() == comag::meta::S_TV ) ? i18n ( "TV" ) : i18n ( "Unknown" ) ); appendItem ( group, "PID", m.getpid() ); appendItem ( group, "Timer", ( unsigned long long ) ( m.gettimer() ) ); } catch ( ... ) { return false; // Exceptions simply means: no meta info } // and finally display it! return true; } return false; }
void QSWindow::durationChanged(qint64 duration){ playTime->setText("00:00.00/"+QTime(0,0).addMSecs(duration).toString("mm:ss.z")); positionSlider->setRange(0, duration); positionSlider->setSingleStep(5<duration/4000.0? 5: duration/4000.0); }
QTime Soprano::DateTime::fromTimeString( const QString& s ) { // ensure the format if( s.length() < 9 || s[2] != ':' || s[5] != ':' ) { qDebug() << Q_FUNC_INFO << " invalid formatted time string: " << s << endl; return QTime(); } bool ok = true; int hh = s.mid( 0, 2 ).toInt( &ok ); if( !ok ) { qDebug() << Q_FUNC_INFO << " invalid formatted time string: " << s << endl; return QTime(); } int mm = s.mid( 3, 2 ).toInt( &ok ); if( !ok ) { qDebug() << Q_FUNC_INFO << " invalid formatted time string: " << s << endl; return QTime(); } int ss = s.mid( 6, 2 ).toInt( &ok ); if( !ok ) { qDebug() << Q_FUNC_INFO << " invalid formatted time string: " << s << endl; return QTime(); } int pos = 8; // parse the fraction of seconds int z = 0; if( s[8] == '.' || s[8] == ',' ) { ++pos; while( s.length() > pos && s[pos].isDigit() ) ++pos; z = s.mid(9, pos-9).leftJustified( 3, '0' ).toInt(&ok); if( !ok ) { qDebug() << Q_FUNC_INFO << " invalid formatted time string: " << s << endl; return QTime(); } } // finally create the time object QTime t( hh, mm, ss, z ); if ( pos >= s.length() ) { qDebug() << Q_FUNC_INFO << " invalid formatted time string: " << s << endl; return QTime(); } // parse the timezone if( s[pos] == 'Z' ) { return t; } else { if( s.length() != pos+6 ) { qDebug() << Q_FUNC_INFO << " invalid formatted timezone string: " << s << endl; return QTime(); } bool add = true; if( s[pos] == '+' ) add = true; else if( s[pos] == '-' ) add = false; else { qDebug() << Q_FUNC_INFO << " invalid formatted timezone string: " << s << endl; return QTime(); } ++pos; hh = s.mid(pos, 2).toInt( &ok ); if( !ok ) { qDebug() << Q_FUNC_INFO << " invalid formatted timezone string: " << s << endl; return QTime(); } pos += 3; mm = s.mid(pos, 2).toInt( &ok ); if( !ok ) { qDebug() << Q_FUNC_INFO << " invalid formatted timezone string: " << s << endl; return QTime(); } int secs = 60*( 60*hh + mm ); if( add ) return t.addSecs( -1*secs ); else return t.addSecs( secs ); } return t; }
/*! * \brief offTime Calculates the number of minutes of off-time taken since start. * \param minOffTime Minimum offtime length in minutes. * \param start Start of contest. QSO's must be after this time to be valid. * \param end End of contest. QSO's must be before this time to be valid. * \return string giving off time */ QString Log::offTime(int minOffTime,QDateTime start,QDateTime end) { QSqlQueryModel m; #if QT_VERSION < 0x050000 m.setQuery("SELECT * FROM log where valid='true'", db); #else m.setQuery("SELECT * FROM log where valid=1", db); #endif while (m.canFetchMore()) { m.fetchMore(); } if (m.rowCount() == 0) { return "Off 00:00/00:00"; // nothing to do } // make sure times are rounded to minutes start=start.addSecs(-start.time().second()); end=end.addSecs(-end.time().second()+60); // need to add 1 minute since end is time of last possible qso int totOffTime=0; QDateTime lastQsoTime=start; for (int i = 0; i < m.rowCount(); i++) { if (!m.record(i).value(SQL_COL_VALID).toBool()) continue; int yr=m.record(i).value(SQL_COL_DATE).toByteArray().right(4).toInt(); int mon=m.record(i).value(SQL_COL_DATE).toByteArray().left(2).toInt(); int d=m.record(i).value(SQL_COL_DATE).toByteArray().mid(2,2).toInt(); int hr=m.record(i).value(SQL_COL_TIME).toByteArray().left(2).toInt(); int min=m.record(i).value(SQL_COL_TIME).toByteArray().right(2).toInt(); QDateTime qsoTime=QDateTime(QDate(yr,mon,d),QTime(hr,min),Qt::UTC); if (qsoTime<start || qsoTime>end) continue; // qso not during contest // calculate time difference from last qso int diff=lastQsoTime.secsTo(qsoTime); if (diff<0) continue; // probably means log is out of order, this will fail! diff/=60; diff--; if (diff>=minOffTime) { totOffTime+=diff; } lastQsoTime=qsoTime; } // add any additional off time taken up to current time int extra=0; if (lastQsoTime<end) { QDateTime current=QDateTime::currentDateTime(); if (end<current) { current=end; } // instead of current time, want only current minute current=current.addSecs(-current.time().second()); extra=lastQsoTime.secsTo(current); extra/=60; extra--; if (extra<0) extra=0; if (extra>=minOffTime) totOffTime+=extra; } if (totOffTime>=6039) { return "Off 00:00/99:99"; } else { int ehr=extra/60; int emin=extra-ehr*60; int hr=totOffTime/60; int min=totOffTime-hr*60; QString tmp="Off "+QString("%1").arg(QString::number(ehr), 2, QChar('0'))+ ":"+QString("%1").arg(QString::number(emin), 2, QChar('0')); tmp=tmp+"/"; tmp=tmp+QString("%1").arg(QString::number(hr), 2, QChar('0'))+ ":"+QString("%1").arg(QString::number(min), 2, QChar('0')); return tmp; } }
RideFile *CsvFileReader::openRideFile(QFile &file, QStringList &errors, QList<RideFile*>*) const { CsvType csvType = generic; QRegExp metricUnits("(km|kph|km/h)", Qt::CaseInsensitive); QRegExp englishUnits("(miles|mph|mp/h)", Qt::CaseInsensitive); QRegExp degCUnits("Temperature .*C", Qt::CaseInsensitive); QRegExp degFUnits("Temperature .*F", Qt::CaseInsensitive); bool metric = true; enum temperature { degF, degC, degNone }; typedef enum temperature Temperature; static Temperature tempType = degNone; QDateTime startTime; // Minutes,Torq (N-m),Km/h,Watts,Km,Cadence,Hrate,ID // Minutes, Torq (N-m),Km/h,Watts,Km,Cadence,Hrate,ID // Minutes,Torq (N-m),Km/h,Watts,Km,Cadence,Hrate,ID,Altitude (m) QRegExp powertapCSV("Minutes,[ ]?Torq \\(N-m\\),(Km/h|MPH),Watts,(Km|Miles),Cadence,Hrate,ID", Qt::CaseInsensitive); // TODO: a more robust regex for ergomo files // i don't have an example with english headers // the ergomo CSV has two rows of headers. units are on the second row. /* ZEIT,STRECKE,POWER,RPM,SPEED,PULS,HÖHE,TEMP,INTERVAL,PAUSE L_SEC,KM,WATT,RPM,KM/H,BPM,METER,°C,NUM,SEC */ QRegExp ergomoCSV("(ZEIT|STRECKE)", Qt::CaseInsensitive); QRegExp motoActvCSV("activity_id", Qt::CaseInsensitive); bool epoch_set = false; quint64 epoch_offset=0; QChar ergomo_separator; int unitsHeader = 1; int total_pause = 0; int currentInterval = 0; int prevInterval = 0; double lastKM=0; // when deriving distance from speed /* Joule 1.0 Version,Date/Time,Km,Minutes,RPE,Tags,"Weight, kg","Work, kJ",FTP,"Sample Rate, s",Device Type,Firmware Version,Last Updated,Category 1,Category 2 6,2012-11-27 13:40:41,0,0,0,,55.8,788,227,1,Joule,18.018,,0, User Name,Power Zone 1,Power Zone 2,Power Zone 3,Power Zone 4,Power Zone 5,Power Zone 6,HR Zone 1,HR Zone 2,HR Zone 3,HR Zone 4,HR Zone 5,Calc Power A,Calc Power B,Calc Power ,0,0,0,0,0,0,150,160,170,180,250,0,-0, Minutes, Torq (N-m),Km/h,Watts,Km,Cadence,Hrate,ID,Altitude (m),Temperature (�C),"Grade, %",Latitude,Longitude,Power Calc'd,Calc Power,Right Pedal,Pedal Power %,Cad. Smoot 0,0,0,45,0,0,69,0,62,16.7,0,0,0,0,0,0,0, */ QRegExp jouleCSV("Device Type,Firmware Version", Qt::CaseInsensitive); QRegExp jouleMetriCSV(",Km,", Qt::CaseInsensitive); // TODO: with all these formats, should the logic change to a switch/case structure? // The iBike format CSV file has five lines of headers (data begins on line 6) // starting with: /* iBike,8,english 2008,8,8,6,32,52 {Various configuration data, recording interval at line[4][4]} Speed (mph),Wind Speed (mph),Power (W),Distance (miles),Cadence (RPM),Heartrate (BPM),Elevation (feet),Hill slope (%),Internal,Internal,Internal,DFPM Power,Latitude,Longitude */ QRegExp iBikeCSV("iBike,\\d\\d?,[a-z]+", Qt::CaseInsensitive); QRegExp moxyCSV("FW Part Number:", Qt::CaseInsensitive); QRegExp gcCSV("secs, cad, hr, km, kph, nm, watts, alt, lon, lat, headwind, slope, temp, interval, lrbalance, lte, rte, lps, rps, smo2, thb, o2hb, hhb"); QRegExp periCSV("mm-dd,hh:mm:ss,SmO2 Live,SmO2 Averaged,THb,Target Power,Heart Rate,Speed,Power,Cadence"); QRegExp freemotionCSV("Stages Data", Qt::CaseInsensitive); QRegExp cpexportCSV("seconds, value,[ model,]* date", Qt::CaseInsensitive); int recInterval = 1; if (!file.open(QFile::ReadOnly)) { errors << ("Could not open ride file: \"" + file.fileName() + "\""); return NULL; } int lineno = 1; QTextStream is(&file); RideFile *rideFile = new RideFile(); int iBikeInterval = 0; bool dfpmExists = false; int iBikeVersion = 0; int secsIndex, minutesIndex = -1; double precWork=0.0; bool eof = false; while (!is.atEnd() && !eof) { // the readLine() method doesn't handle old Macintosh CR line endings // this workaround will load the the entire file if it has CR endings // then split and loop through each line // otherwise, there will be nothing to split and it will read each line as expected. QString linesIn = is.readLine(); QStringList lines = linesIn.split('\r'); // workaround for empty lines if(lines.isEmpty()) { lineno++; continue; } for (int li = 0; li < lines.size(); ++li) { QString line = lines[li]; if (line.length()==0) { continue; } if (lineno == 1) { if (ergomoCSV.indexIn(line) != -1) { csvType = ergomo; rideFile->setDeviceType("Ergomo"); rideFile->setFileFormat("Ergomo CSV (csv)"); unitsHeader = 2; QStringList headers = line.split(';'); if (headers.size()>1) ergomo_separator = ';'; else ergomo_separator = ','; ++lineno; continue; } else if(iBikeCSV.indexIn(line) != -1) { csvType = ibike; rideFile->setDeviceType("iBike"); rideFile->setFileFormat("iBike CSV (csv)"); unitsHeader = 5; iBikeVersion = line.section( ',', 1, 1 ).toInt(); ++lineno; continue; } else if(motoActvCSV.indexIn(line) != -1) { csvType = motoactv; rideFile->setDeviceType("MotoACTV"); rideFile->setFileFormat("MotoACTV CSV (csv)"); unitsHeader = -1; /* MotoACTV files are always metric */ metric = true; ++lineno; continue; } else if(jouleCSV.indexIn(line) != -1) { csvType = joule; rideFile->setDeviceType("Joule"); rideFile->setFileFormat("Joule CSV (csv)"); if(jouleMetriCSV.indexIn(line) != -1) { unitsHeader = 5; metric = true; } else { /* ? */ } ++lineno; continue; } else if(moxyCSV.indexIn(line) != -1) { csvType = moxy; rideFile->setDeviceType("Moxy"); rideFile->setFileFormat("Moxy CSV (csv)"); unitsHeader = 4; recInterval = 1; ++lineno; continue; } else if(gcCSV.indexIn(line) != -1) { csvType = gc; rideFile->setDeviceType("GoldenCheetah"); rideFile->setFileFormat("GoldenCheetah CSV (csv)"); unitsHeader = 1; recInterval = 1; ++lineno; continue; } else if(periCSV.indexIn(line) != -1) { csvType = peripedal; rideFile->setDeviceType("Peripedal"); rideFile->setFileFormat("Peripedal CSV (csv)"); unitsHeader = 1; recInterval = 1; ++lineno; continue; } else if(powertapCSV.indexIn(line) != -1) { csvType = powertap; rideFile->setDeviceType("PowerTap"); rideFile->setFileFormat("PowerTap CSV (csv)"); unitsHeader = 1; ++lineno; continue; } else if(freemotionCSV.indexIn(line) != -1) { csvType = freemotion; rideFile->setDeviceType("Freemotion Bike"); rideFile->setFileFormat("Stages Data (csv)"); unitsHeader = 3; ++lineno; continue; } else if(cpexportCSV.indexIn(line) != -1) { csvType = cpexport; rideFile->setDeviceType("CP Plot Export"); rideFile->setFileFormat("CP Plot Export (csv)"); unitsHeader = 1; ++lineno; continue; } else { // default csvType = generic; rideFile->setDeviceType("Unknow"); rideFile->setFileFormat("Generic CSV (csv)"); } } if (csvType == ibike) { if (lineno == 2) { QStringList f = line.split(","); if (f.size() == 6) { startTime = QDateTime( QDate(f[0].toInt(), f[1].toInt(), f[2].toInt()), QTime(f[3].toInt(), f[4].toInt(), f[5].toInt())); } } else if (lineno == 4) { // this is the line with the iBike configuration data // recording interval is in the [4] location (zero-based array) // the trailing zeroes in the configuration area seem to be causing an error // the number is in the format 5.000000 recInterval = (int)line.section(',',4,4).toDouble(); } } if (csvType == freemotion) { if (lineno == 2) { if (line == "English") metric = false; } } if (csvType == joule && lineno == 2) { // 6,2012-11-27 13:40:41,0,0,0,,55.8,788,227,1,Joule,18.018,,0, QStringList f = line.split(","); if (f.size() >= 2) { int f0l; QStringList f0 = f[1].split("|"); // new format? due to new PowerAgent version (7.5.7.34)? // 6,2011-01-02 21:22:20|2011-01-02 21:22|01/02/2011 21:22|2011-01-02 21-22-20,0,0, ... f0l = f0.size(); if (f0l >= 2) { startTime = QDateTime::fromString(f0[0], "yyyy-MM-dd H:mm:ss"); } else { startTime = QDateTime::fromString(f[1], "yyyy-MM-dd H:mm:ss"); } } } if (lineno == unitsHeader && csvType == generic) { QRegExp timeHeaderSecs("( )*(secs|sec|time)( )*", Qt::CaseInsensitive); QRegExp timeHeaderMins("( )*(min|minutes)( )*", Qt::CaseInsensitive); QStringList headers = line.split(","); QStringListIterator i(headers); while (i.hasNext()) { QString header = i.next(); if (timeHeaderSecs.indexIn(header) != -1) { secsIndex = headers.indexOf(header); } else if (timeHeaderMins.indexIn(header) != -1) { minutesIndex = headers.indexOf(header); } } } else if (lineno == unitsHeader && csvType != moxy && csvType != peripedal) { if (metricUnits.indexIn(line) != -1) metric = true; else if (englishUnits.indexIn(line) != -1) metric = false; else { errors << "Can't find units in first line: \"" + line + "\" of file \"" + file.fileName() + "\"."; delete rideFile; file.close(); return NULL; } if (degCUnits.indexIn(line) != -1) tempType = degC; else if (degFUnits.indexIn(line) != -1) tempType = degF; } else if (lineno > unitsHeader) { double minutes=0,nm=0,kph=0,watts=0,km=0,cad=0,alt=0,hr=0,dfpm=0, seconds=0.0; double temp=RideFile::NoTemp; double slope=0.0; bool ok; double lat = 0.0, lon = 0.0; double headwind = 0.0; double lrbalance = 0.0; double lte = 0.0, rte = 0.0; double lps = 0.0, rps = 0.0; double smo2 = 0.0, thb = 0.0; double o2hb = 0.0, hhb = 0.0; int interval=0; int pause=0; quint64 ms; if (csvType == powertap || csvType == joule) { minutes = line.section(',', 0, 0).toDouble(); nm = line.section(',', 1, 1).toDouble(); kph = line.section(',', 2, 2).toDouble(); watts = line.section(',', 3, 3).toDouble(); km = line.section(',', 4, 4).toDouble(); cad = line.section(',', 5, 5).toDouble(); hr = line.section(',', 6, 6).toDouble(); interval = line.section(',', 7, 7).toInt(); alt = line.section(',', 8, 8).toDouble(); if (csvType == joule && tempType != degNone) { // is the position always the same? // should we read the header and assign positions // to each item instead? temp = line.section(',', 9, 9).toDouble(); if (tempType == degF) { // convert to deg C temp *= FAHRENHEIT_PER_CENTIGRADE + FAHRENHEIT_ADD_CENTIGRADE; } } if (!metric) { km *= KM_PER_MILE; kph *= KM_PER_MILE; alt *= METERS_PER_FOOT; } } else if (csvType == gc) { // GoldenCheetah CVS Format "secs, cad, hr, km, kph, nm, watts, alt, lon, lat, headwind, slope, temp, interval, lrbalance, lte, rte, lps, rps, smo2, thb, o2hb, hhb\n"; seconds = line.section(',', 0, 0).toDouble(); minutes = seconds / 60.0f; cad = line.section(',', 1, 1).toDouble(); hr = line.section(',', 2, 2).toDouble(); km = line.section(',', 3, 3).toDouble(); kph = line.section(',', 4, 4).toDouble(); nm = line.section(',', 5, 5).toDouble(); watts = line.section(',', 6, 6).toDouble(); alt = line.section(',', 7, 7).toDouble(); lon = line.section(',', 8, 8).toDouble(); lat = line.section(',', 9, 9).toDouble(); headwind = line.section(',', 10, 10).toDouble(); slope = line.section(',', 11, 11).toDouble(); temp = line.section(',', 12, 12).toDouble(); interval = line.section(',', 13, 13).toInt(); lrbalance = line.section(',', 14, 14).toInt(); lte = line.section(',', 15, 15).toInt(); rte = line.section(',', 16, 16).toInt(); lps = line.section(',', 17, 17).toInt(); rps = line.section(',', 18, 18).toInt(); smo2 = line.section(',', 19, 19).toInt(); thb = line.section(',', 20, 20).toInt(); o2hb = line.section(',', 21, 21).toInt(); hhb = line.section(',', 22, 22).toInt(); } else if (csvType == peripedal) { //mm-dd,hh:mm:ss,SmO2 Live,SmO2 Averaged,THb,Target Power,Heart Rate,Speed,Power,Cadence // ignore lines with wrong number of entries if (line.split(",").count() != 10) continue; seconds = moxySeconds(line.section(',',1,1)); minutes = seconds / 60.0f; if (startTime == QDateTime()) { QDate date = periDate(line.section(',',0,0)); QTime time = QTime(0,0,0).addSecs(seconds); startTime = QDateTime(date,time); } double aSmo2 = line.section(',', 3, 3).toDouble(); smo2 = line.section(',', 2, 2).toDouble(); // use average if live not available if (aSmo2 && !smo2) smo2 = aSmo2; thb = line.section(',', 4, 4).toDouble(); hr = line.section(',', 6, 6).toDouble(); kph = line.section(',', 7, 7).toDouble(); watts = line.section(',', 8, 8).toDouble(); cad = line.section(',', 10, 10).toDouble(); // dervice distance from speed km = lastKM + (kph/3600.0f); lastKM = km; nm = 0; alt = 0; lon = 0; lat = 0; headwind = 0; slope = 0; temp = 0; interval = 0; lrbalance = 0; lte = 0; rte = 0; lps = 0; rps = 0; o2hb = 0; hhb = 0; } else if (csvType == freemotion) { if (line == "Ride_Totals") { eof = true; continue; } // Time,Miles,MPH,Watts,HR,RPM seconds = QTime::fromString(line.section(',', 0, 0), "m:s").second(); minutes = QTime::fromString(line.section(',', 0, 0), "m:s").minute() + seconds / 60.0f; cad = line.section(',', 5, 5).toDouble(); hr = line.section(',', 4, 4).toDouble(); km = line.section(',', 1, 1).toDouble(); kph = line.section(',', 2, 2).toDouble(); watts = line.section(',', 3, 3).toDouble(); if (!metric) { km *= KM_PER_MILE; kph *= KM_PER_MILE; } } else if (csvType == ibike) { // this must be iBike // can't find time as a column. // will we have to extrapolate based on the recording interval? // reading recording interval from config data in ibike csv file // // For iBike software version 11 or higher: // use "power" field until a the "dfpm" field becomes non-zero. minutes = (recInterval * lineno - unitsHeader)/60.0; nm = 0; //no torque kph = line.section(',', 0, 0).toDouble(); dfpm = line.section( ',', 11, 11).toDouble(); headwind = line.section(',', 1, 1).toDouble(); if( iBikeVersion >= 11 && ( dfpm > 0.0 || dfpmExists ) ) { dfpmExists = true; watts = dfpm; } else { watts = line.section(',', 2, 2).toDouble(); } km = line.section(',', 3, 3).toDouble(); cad = line.section(',', 4, 4).toDouble(); hr = line.section(',', 5, 5).toDouble(); alt = line.section(',', 6, 6).toDouble(); slope = line.section(',', 7, 7).toDouble(); temp = line.section(',', 8, 8).toDouble(); lat = line.section(',', 12, 12).toDouble(); lon = line.section(',', 13, 13).toDouble(); int lap = line.section(',', 9, 9).toInt(); if (lap > 0) { iBikeInterval += 1; interval = iBikeInterval; } if (!metric) { km *= KM_PER_MILE; kph *= KM_PER_MILE; alt *= METERS_PER_FOOT; headwind *= KM_PER_MILE; } } else if (csvType == moxy) { // we get crappy lines with no data so ignore them // I think they're supposed to be delimiters for the file // content, but are just noise to us ! if (line == (" ,,,,,") || line == ",,,,," || line == "" || line == " ") continue; // need to get time from second column and note that // there will be gaps when recording drops so shouldn't // assume it is a continuous stream double seconds = moxySeconds(line.section(',',1,1)); if (startTime == QDateTime()) { QDate date = moxyDate(line.section(',',0,0)); QTime time = QTime(0,0,0).addSecs(seconds); startTime = QDateTime(date,time); } if (seconds >0) { minutes = seconds / 60.0f; smo2 = line.section(',', 2, 2).remove("\"").toDouble(); thb = line.section(',', 4, 4).remove("\"").toDouble(); } } else if(csvType == motoactv) { /* MotoActv saves it all as kind of SI (m, ms, m/s, NM etc) * "double","double",.. so we need to filter out " */ km = line.section(',', 0,0).remove("\"").toDouble()/1000; hr = line.section(',', 2, 2).remove("\"").toDouble(); kph = line.section(',', 3, 3).remove("\"").toDouble()*3.6; lat = line.section(',', 5, 5).remove("\"").toDouble(); /* Item 8 is crank torque, 13 is wheel torque */ nm = line.section(',', 8, 8).remove("\"").toDouble(); /* Ok there's no crank torque, try the wheel */ if(nm == 0.0) { nm = line.section(',', 13, 13).remove("\"").toDouble(); } if(epoch_set == false) { epoch_set = true; epoch_offset = line.section(',', 9,9).remove("\"").toULongLong(&ok, 10); /* We use this first value as the start time */ startTime = QDateTime(); startTime.setMSecsSinceEpoch(epoch_offset); rideFile->setStartTime(startTime); } ms = line.section(',', 9,9).remove("\"").toULongLong(&ok, 10); ms -= epoch_offset; seconds = ms/1000; alt = line.section(',', 10, 10).remove("\"").toDouble(); watts = line.section(',', 11, 11).remove("\"").toDouble(); lon = line.section(',', 15, 15).remove("\"").toDouble(); cad = line.section(',', 16, 16).remove("\"").toDouble(); } else if (csvType == ergomo) { // for ergomo formatted CSV files minutes = line.section(ergomo_separator, 0, 0).toDouble() + total_pause; QString km_string = line.section(ergomo_separator, 1, 1); km_string.replace(",","."); km = km_string.toDouble(); watts = line.section(ergomo_separator, 2, 2).toDouble(); cad = line.section(ergomo_separator, 3, 3).toDouble(); QString kph_string = line.section(ergomo_separator, 4, 4); kph_string.replace(",","."); kph = kph_string.toDouble(); hr = line.section(ergomo_separator, 5, 5).toDouble(); alt = line.section(ergomo_separator, 6, 6).toDouble(); interval = line.section(',', 8, 8).toInt(); if (interval != prevInterval) { prevInterval = interval; if (interval != 0) currentInterval++; } if (interval != 0) interval = currentInterval; pause = line.section(ergomo_separator, 9, 9).toInt(); total_pause += pause; nm = 0; // torque is not provided in the Ergomo file // the ergomo records the time in whole seconds // RECORDING INT. 1, 2, 5, 10, 15 or 30 per sec // Time is *always* perfectly sequential. To find pauses, // you need to read the PAUSE column. minutes = minutes/60.0; if (!metric) { km *= KM_PER_MILE; kph *= KM_PER_MILE; alt *= METERS_PER_FOOT; } } else if (csvType == cpexport) { // seconds, value, (model), date seconds = line.section(',',0,0).toDouble(); minutes = seconds / 60.0f; seconds = lineno -1 ; double avgwatts = line.section(',', 1, 1).toDouble(); watts = avgwatts * seconds - precWork; // 1000 * 1 - 700 precWork = avgwatts * seconds; } else { if (secsIndex > -1) { seconds = line.section(',', secsIndex, secsIndex).toDouble(); minutes = seconds / 60.0f; } } // PT reports no data as watts == -1. if (watts == -1) watts = 0; if(csvType == motoactv) rideFile->appendPoint(seconds, cad, hr, km, kph, nm, watts, alt, lon, lat, 0.0, 0.0, temp, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, interval); else if (csvType == moxy) { // hack it in for now // XXX IT COULD BE RECORDED WITH DIFFERENT INTERVALS XXX rideFile->appendPoint(minutes * 60.0, cad, hr, km, kph, nm, watts, alt, lon, lat, headwind, slope, temp, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, smo2, thb, 0.0, 0.0, 0.0, interval); rideFile->appendPoint((minutes * 60.0)+1, cad, hr, km, // dupe it so we have 1s recording easier to merge kph, nm, watts, alt, lon, lat, headwind, slope, temp, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, smo2, thb, 0.0, 0.0, 0.0, interval); } else { rideFile->appendPoint(minutes * 60.0, cad, hr, km, kph, nm, watts, alt, lon, lat, headwind, slope, temp, lrbalance, lte, rte, lps, rps, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, smo2, thb, 0.0, 0.0, 0.0, interval); } } ++lineno; } } file.close(); // To estimate the recording interval, take the median of the // first 1000 samples and round to nearest millisecond. int n = rideFile->dataPoints().size(); n = qMin(n, 1000); if (n >= 2) { QVector<double> secs(n-1); for (int i = 0; i < n-1; ++i) { double now = rideFile->dataPoints()[i]->secs; double then = rideFile->dataPoints()[i+1]->secs; secs[i] = then - now; } std::sort(secs.begin(), secs.end()); int mid = n / 2 - 1; double recint = round(secs[mid] * 1000.0) / 1000.0; rideFile->setRecIntSecs(recint); } // less than 2 data points is not a valid ride file else { errors << "Insufficient valid data in file \"" + file.fileName() + "\"."; delete rideFile; file.close(); return NULL; } QRegExp rideTime("^.*/(\\d\\d\\d\\d)_(\\d\\d)_(\\d\\d)_" "(\\d\\d)_(\\d\\d)_(\\d\\d)\\.csv$"); rideTime.setCaseSensitivity(Qt::CaseInsensitive); if (startTime != QDateTime()) { // Start time was already set above? rideFile->setStartTime(startTime); } else if (rideTime.indexIn(file.fileName()) >= 0) { // It matches the GC naming convention? QDateTime datetime(QDate(rideTime.cap(1).toInt(), rideTime.cap(2).toInt(), rideTime.cap(3).toInt()), QTime(rideTime.cap(4).toInt(), rideTime.cap(5).toInt(), rideTime.cap(6).toInt())); rideFile->setStartTime(datetime); } else { // Could be yyyyddmm_hhmmss_NAME.csv (case insensitive) rideTime.setPattern("(\\d\\d\\d\\d)(\\d\\d)(\\d\\d)_(\\d\\d)(\\d\\d)(\\d\\d)[^\\.]*\\.csv$"); if (rideTime.indexIn(file.fileName()) >= 0) { QDateTime datetime(QDate(rideTime.cap(1).toInt(), rideTime.cap(2).toInt(), rideTime.cap(3).toInt()), QTime(rideTime.cap(4).toInt(), rideTime.cap(5).toInt(), rideTime.cap(6).toInt())); rideFile->setStartTime(datetime); } else { // is it in poweragent format "name yyyy-mm-dd hh-mm-ss.csv" rideTime.setPattern("(\\d\\d\\d\\d)-(\\d\\d)-(\\d\\d) (\\d\\d)-(\\d\\d)-(\\d\\d)\\.csv$"); if (rideTime.indexIn(file.fileName()) >=0) { QDateTime datetime(QDate(rideTime.cap(1).toInt(), rideTime.cap(2).toInt(), rideTime.cap(3).toInt()), QTime(rideTime.cap(4).toInt(), rideTime.cap(5).toInt(), rideTime.cap(6).toInt())); rideFile->setStartTime(datetime); } else { // NO DICE // Note: qWarning("Failed to set start time"); // console messages are no use, so commented out // this problem will ONLY occur during the import // process which traps these and corrects them // so no need to do anything here } } } // did we actually read any samples? if (rideFile->dataPoints().count() > 0) { return rideFile; } else { errors << "No samples present."; delete rideFile; return NULL; } }
RealtimeWindow::RealtimeWindow(MainWindow *parent, TrainTool *trainTool, const QDir &home) : QWidget(parent) { // set home this->home = home; this->trainTool = trainTool; main = parent; deviceController = NULL; streamController = NULL; ergFile = NULL; // metric or imperial? boost::shared_ptr<QSettings> settings = GetApplicationSettings(); QVariant unit = settings->value(GC_UNIT); useMetricUnits = (unit.toString() == "Metric"); // main layout for the window main_layout = new QVBoxLayout(this); timer_layout = new QGridLayout(); // BUTTONS AND LCDS button_layout = new QHBoxLayout(); option_layout = new QHBoxLayout(); controls_layout = new QVBoxLayout(); deviceSelector = new QComboBox(this); streamSelector = new QComboBox(this); // get configured devices DeviceConfigurations all; Devices = all.getList(); streamSelector->addItem("No streaming", -1); for (int i=0; i<Devices.count(); i++) { // add streamers if ( Devices.at(i).type == DEV_GSERVER || Devices.at(i).type == DEV_GCLIENT ) streamSelector->addItem(Devices.at(i).name, i); // add data sources deviceSelector->addItem(Devices.at(i).name, i); } deviceSelector->setCurrentIndex(0); streamSelector->setCurrentIndex(0); recordSelector = new QCheckBox(this); recordSelector->setText(tr("Save")); recordSelector->setChecked(Qt::Checked); startButton = new QPushButton(tr("Start"), this); startButton->setMaximumHeight(100); pauseButton = new QPushButton(tr("Pause"), this); pauseButton->setMaximumHeight(100); stopButton = new QPushButton(tr("Stop"), this); stopButton->setMaximumHeight(100); button_layout->addWidget(startButton); button_layout->addWidget(pauseButton); button_layout->addWidget(stopButton); option_layout->addWidget(deviceSelector); option_layout->addSpacing(10); option_layout->addWidget(recordSelector); option_layout->addSpacing(10); option_layout->addWidget(streamSelector); // XXX NETWORK STREAMING DISABLED IN THIS RELEASE SO HIDE THE COMBO streamSelector->hide(); option_layout->addSpacing(10); controls_layout->addItem(option_layout); controls_layout->addItem(button_layout); // handle config changes connect(main, SIGNAL(configChanged()), this, SLOT(configUpdate())); connect(deviceSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(SelectDevice(int))); connect(recordSelector, SIGNAL(clicked()), this, SLOT(SelectRecord())); connect(streamSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(SelectStream(int))); connect(trainTool, SIGNAL(workoutSelected()), this, SLOT(SelectWorkout())); if (Devices.count() > 0) { connect(startButton, SIGNAL(clicked()), this, SLOT(Start())); connect(pauseButton, SIGNAL(clicked()), this, SLOT(Pause())); connect(stopButton, SIGNAL(clicked()), this, SLOT(Stop())); } else { connect(startButton, SIGNAL(clicked()), this, SLOT(warnnoConfig())); connect(pauseButton, SIGNAL(clicked()), this, SLOT(warnnoConfig())); connect(stopButton, SIGNAL(clicked()), this, SLOT(warnnoConfig())); } powerLabel = new QLabel(tr("WATTS"), this); powerLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); heartrateLabel = new QLabel(tr("BPM"), this); heartrateLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); speedLabel = new QLabel(useMetricUnits ? tr("KPH") : tr("MPH"), this); speedLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); cadenceLabel = new QLabel(tr("RPM"), this); cadenceLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); lapLabel = new QLabel(tr("Lap/Interval"), this); lapLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); loadLabel = new QLabel(tr("Load WATTS"), this); loadLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); distanceLabel = new QLabel(useMetricUnits ? tr("Distance (KM)") : tr("Distance (Miles)"), this); distanceLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); avgpowerLabel = new QLabel(tr("Avg WATTS"), this); avgpowerLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); avgheartrateLabel = new QLabel(tr("Avg BPM"), this); avgheartrateLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); avgspeedLabel = new QLabel(useMetricUnits ? tr("Avg KPH") : tr("Avg MPH"), this); avgspeedLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); avgcadenceLabel = new QLabel(tr("Avg RPM"), this); avgcadenceLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); avgloadLabel = new QLabel(tr("Avg Load WATTS"), this); avgloadLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); laptimeLabel = new QLabel(tr("LAP TIME"), this); laptimeLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); timeLabel = new QLabel(tr("TIME"), this); timeLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); powerLCD = new QLCDNumber(this); powerLCD->setSegmentStyle(QLCDNumber::Filled); heartrateLCD = new QLCDNumber(this); heartrateLCD->setSegmentStyle(QLCDNumber::Filled); speedLCD = new QLCDNumber(this); speedLCD->setSegmentStyle(QLCDNumber::Filled); cadenceLCD = new QLCDNumber(this); cadenceLCD->setSegmentStyle(QLCDNumber::Filled); lapLCD = new QLCDNumber(this); lapLCD->setSegmentStyle(QLCDNumber::Filled); loadLCD = new QLCDNumber(this); loadLCD->setSegmentStyle(QLCDNumber::Filled); distanceLCD = new QLCDNumber(this); distanceLCD->setSegmentStyle(QLCDNumber::Filled); avgpowerLCD = new QLCDNumber(this); avgpowerLCD->setSegmentStyle(QLCDNumber::Filled); avgheartrateLCD = new QLCDNumber(this); avgheartrateLCD->setSegmentStyle(QLCDNumber::Filled); avgspeedLCD = new QLCDNumber(this); avgspeedLCD->setSegmentStyle(QLCDNumber::Filled); avgcadenceLCD = new QLCDNumber(this); avgcadenceLCD->setSegmentStyle(QLCDNumber::Filled); avgloadLCD = new QLCDNumber(this); avgloadLCD->setSegmentStyle(QLCDNumber::Filled); laptimeLCD = new QLCDNumber(this); laptimeLCD->setSegmentStyle(QLCDNumber::Filled); laptimeLCD->setNumDigits(9); timeLCD = new QLCDNumber(this); timeLCD->setSegmentStyle(QLCDNumber::Filled); timeLCD->setNumDigits(9); gridLayout = new QGridLayout(); gridLayout->addWidget(powerLabel, 1, 0); gridLayout->addWidget(cadenceLabel, 1, 1); gridLayout->addWidget(heartrateLabel, 1, 2); gridLayout->addWidget(speedLabel, 1, 3); gridLayout->addWidget(distanceLabel, 1, 4); gridLayout->addWidget(lapLabel, 1, 5); gridLayout->addWidget(powerLCD, 2, 0); gridLayout->addWidget(cadenceLCD, 2, 1); gridLayout->addWidget(heartrateLCD, 2, 2); gridLayout->addWidget(speedLCD, 2, 3); gridLayout->addWidget(distanceLCD, 2, 4); gridLayout->addWidget(lapLCD, 2, 5); gridLayout->addWidget(avgpowerLabel, 3, 0); gridLayout->addWidget(avgcadenceLabel, 3, 1); gridLayout->addWidget(avgheartrateLabel, 3, 2); gridLayout->addWidget(avgspeedLabel, 3, 3); gridLayout->addWidget(avgloadLabel, 3, 4); gridLayout->addWidget(loadLabel, 3, 5); gridLayout->addWidget(loadLCD, 4, 5); gridLayout->addWidget(avgpowerLCD, 4, 0); gridLayout->addWidget(avgcadenceLCD, 4, 1); gridLayout->addWidget(avgheartrateLCD, 4, 2); gridLayout->addWidget(avgspeedLCD, 4, 3); gridLayout->addWidget(avgloadLCD, 4, 4); gridLayout->setRowStretch(2, 4); gridLayout->setRowStretch(4, 3); // timers etc timer_layout->addWidget(timeLabel, 0, 0); timer_layout->addWidget(laptimeLabel, 0, 3); timer_layout->addWidget(timeLCD, 1, 0); timer_layout->addItem(controls_layout, 1,1); timer_layout->addWidget(laptimeLCD, 1, 3); timer_layout->setRowStretch(0, 1); timer_layout->setRowStretch(1, 4); // REALTIME PLOT rtPlot = new RealtimePlot(); connect(main, SIGNAL(configChanged()), rtPlot, SLOT(configChanged())); // COURSE PLOT ergPlot = new ErgFilePlot(0); ergPlot->setVisible(false); // LAYOUT main_layout->addWidget(ergPlot); main_layout->addItem(timer_layout); main_layout->addItem(gridLayout); main_layout->addWidget(rtPlot); displaymode=2; main_layout->setStretch(0,1); main_layout->setStretch(1,1); main_layout->setStretch(2,2); main_layout->setStretch(3, displaymode); // now the GUI is setup lets sort our control variables gui_timer = new QTimer(this); disk_timer = new QTimer(this); stream_timer = new QTimer(this); load_timer = new QTimer(this); session_time = QTime(); session_elapsed_msec = 0; lap_time = QTime(); lap_elapsed_msec = 0; recordFile = NULL; status = 0; status |= RT_RECORDING; // recording is on by default! - add others here status |= RT_MODE_ERGO; // ergo mode by default displayWorkoutLap = displayLap = 0; pwrcount = 0; cadcount = 0; hrcount = 0; spdcount = 0; lodcount = 0; load_msecs = total_msecs = lap_msecs = 0; displayWorkoutDistance = displayDistance = displayPower = displayHeartRate = displaySpeed = displayCadence = displayGradient = displayLoad = 0; avgPower= avgHeartRate= avgSpeed= avgCadence= avgLoad= 0; connect(gui_timer, SIGNAL(timeout()), this, SLOT(guiUpdate())); connect(disk_timer, SIGNAL(timeout()), this, SLOT(diskUpdate())); connect(stream_timer, SIGNAL(timeout()), this, SLOT(streamUpdate())); connect(load_timer, SIGNAL(timeout()), this, SLOT(loadUpdate())); // setup the controller based upon currently selected device setDeviceController(); rtPlot->replot(); }
* along with the EPICS QT Framework. If not, see <http://www.gnu.org/licenses/>. * * Copyright (c) 2009, 2010 * * Author: * Andrew Rhyder * Contact details: * [email protected] */ #include <QString> #include <QTextStream> #include <QCaDateTime.h> #include <QDebug> static const QDateTime qtEpoch (QDate( 1970, 1, 1 ), QTime( 0, 0, 0, 0 ), Qt::UTC ); static const QDateTime epicsEpoch (QDate( 1990, 1, 1 ), QTime( 0, 0, 0, 0 ), Qt::UTC ); static unsigned long EPICSQtEpocOffset = qtEpoch.secsTo ( epicsEpoch ); /* Qt 4.6 does not have the msecsTo function - so we roll our own. Return the number of milliseconds from this datetime to the other datetime. If the other datetime is earlier than this datetime, the value returned is negative. Based on msecsTo out of qt-everywhere-opensource-src-4.8.4/src/corelib/tools/qdatetime.cpp */ static qint64 msecsTo_48 (const QDateTime& self, const QDateTime& other) { #if (QT_VERSION >= QT_VERSION_CHECK(4, 8, 0)) return self.msecsTo( other );
void DiarySidebar::setSummary() { // are we metric? bool useMetricUnits = context->athlete->useMetricUnits; // where we construct the text QString summaryText(""); QDate when; if (_ride && _ride->ride()) when = _ride->dateTime.date(); else when = QDate::currentDate(); // main totals static const QStringList totalColumn = QStringList() << "workout_time" << "time_riding" << "total_distance" << "total_work" << "elevation_gain"; static const QStringList averageColumn = QStringList() << "average_speed" << "average_power" << "average_hr" << "average_cad"; static const QStringList maximumColumn = QStringList() << "max_speed" << "max_power" << "max_heartrate" << "max_cadence"; // user defined QString s = appsettings->value(this, GC_SETTINGS_SUMMARY_METRICS, GC_SETTINGS_SUMMARY_METRICS_DEFAULT).toString(); // in case they were set tand then unset if (s == "") s = GC_SETTINGS_SUMMARY_METRICS_DEFAULT; QStringList metricColumn = s.split(","); // what date range should we use? QDate newFrom, newTo; switch(summarySelect->currentIndex()) { case 0 : // DAILY - just the date of the ride newFrom = newTo = when; break; case 1 : // WEEKLY - from Mon to Sun newFrom = when.addDays((when.dayOfWeek()-1)*-1); newTo = newFrom.addDays(6); break; default: case 2 : // MONTHLY - all days in month newFrom = QDate(when.year(), when.month(), 1); newTo = newFrom.addMonths(1).addDays(-1); break; } if (newFrom != from || newTo != to) { // date range changed lets refresh from = newFrom; to = newTo; // lets get the metrics QList<SummaryMetrics>results = context->athlete->metricDB->getAllMetricsFor(QDateTime(from,QTime(0,0,0)), QDateTime(to, QTime(24,59,59))); // foreach of the metrics get an aggregated value // header of summary summaryText = QString("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 3.2//EN\">" "<html>" "<head>" "<title></title>" "</head>" "<body>" "<center>"); for (int i=0; i<4; i++) { //taken out maximums -- too much info -- looks ugly QString aggname; QStringList list; switch(i) { case 0 : // Totals aggname = tr("Totals"); list = totalColumn; break; case 1 : // Averages aggname = tr("Averages"); list = averageColumn; break; case 3 : // Maximums aggname = tr("Maximums"); list = maximumColumn; break; case 2 : // User defined.. aggname = tr("Metrics"); list = metricColumn; break; } summaryText += QString("<p><table width=\"85%\">" "<tr>" "<td align=\"center\" colspan=\"2\">" "<b>%1</b>" "</td>" "</tr>").arg(aggname); foreach(QString metricname, list) { const RideMetric *metric = RideMetricFactory::instance().rideMetric(metricname); QStringList empty; // usually for filters, but we don't do that QString value = SummaryMetrics::getAggregated(context, metricname, results, empty, false, useMetricUnits); // Maximum Max and Average Average looks nasty, remove from name for display QString s = metric ? metric->name().replace(QRegExp(tr("^(Average|Max) ")), "") : "unknown"; // don't show units for time values if (metric && (metric->units(useMetricUnits) == "seconds" || metric->units(useMetricUnits) == tr("seconds") || metric->units(useMetricUnits) == "")) { summaryText += QString("<tr><td>%1:</td><td align=\"right\"> %2</td>") .arg(s) .arg(value); } else { summaryText += QString("<tr><td>%1(%2):</td><td align=\"right\"> %3</td>") .arg(s) .arg(metric ? metric->units(useMetricUnits) : "unknown") .arg(value); } } summaryText += QString("</tr>" "</table>"); } // finish off the html document summaryText += QString("</center>" "</body>" "</html>"); // set webview contents summary->page()->mainFrame()->setHtml(summaryText); }