Пример #1
0
int main(int argc, char ** argv) {
   QApplication app{argc, argv};
   QWidget w;
   QFormLayout layout{&w};
   QLineEdit address;
   layout.addRow("Address to look up", &address);
   QLabel result;
   layout.addRow("Result", &result);
   QPushButton lookup{"Lookup"};
   layout.addRow(&lookup);
   lookup.setDefault(true);
   w.show();

   IfLookup ifLookup;
   QObject::connect(&lookup, &QPushButton::clicked, [&]{
      result.clear();
      ifLookup.lookup(address.text());
   });
   QObject::connect(&ifLookup, &IfLookup::hasResult, [&](IfLookup::Result r){
      static const QMap<IfLookup::Result, QString> msgs = {
         { IfLookup::Local, "Local" }, { IfLookup::NonLocal, "Non-Local" },
         { IfLookup::TimedOut, "Timed Out" }, { IfLookup::Error, "Lookup Error" }
      };
      result.setText(msgs.value(r));
   });

   return app.exec();
}
Пример #2
0
void BinCalcWidget::clearButtonClicked()
{
    QLineEdit *lineEdit = findChild<QLineEdit *>();
    if( lineEdit == 0 )
        return;
    QLabel *label = findChild<QLabel *>();
    if( label == 0 )
        return;

    lineEdit->clear();
    label->clear();
    m_operator.clear();
    m_value = 0;
}
Пример #3
0
void LapTimeComparisonDialog::updateCharts()
{
    DriverData *driverData[4] = {0, 0, 0, 0};
    QString driver;
    for (int i = 0; i < 4; ++i)
    {
        int idx = eventData.getDriverId(getNumber(i));
        if (idx > 0)
        {
            driver = eventData.getDriversData()[idx-1].getDriverName();
            driverData[i] = &eventData.getDriversData()[idx-1];
//            carIdx = (eventData.getDriversData()[idx-1].getNumber() > 13 ?
//                             eventData.getDriversData()[idx-1].getNumber() - 2 :
//                             eventData.getDriversData()[idx-1].getNumber() - 1) / 2;

            QTableWidgetItem *item = ui->chartsTableWidget->item(0, i);
            item->setText(driver);
            item->setTextColor(ColorsManager::getInstance().getCarColor(driverData[i]->getNumber()));

//            if (carIdx >= 0)
            {
                QLabel *lab = qobject_cast<QLabel*>(ui->chartsTableWidget->cellWidget(1, i));
                if (!lab)
                {
                    lab = new QLabel();
                    lab->setAlignment(Qt::AlignCenter);
                    lab->setPixmap(ImagesFactory::getInstance().getCarThumbnailsFactory().getCarThumbnail(driverData[i]->getNumber(), thumbnailsSize));//eventData.carImages[carIdx].scaledToWidth(120, Qt::SmoothTransformation));
                    ui->chartsTableWidget->setCellWidget(1, i, lab);
                }
                else
                    lab->setPixmap(ImagesFactory::getInstance().getCarThumbnailsFactory().getCarThumbnail(driverData[i]->getNumber(), thumbnailsSize));//eventData.carImages[carIdx].scaledToWidth(120, Qt::SmoothTransformation));
            }
        }
        else
        {
            QTableWidgetItem *item = ui->chartsTableWidget->item(0, i);
            item->setText("");

            QLabel *lab = qobject_cast<QLabel*>(ui->chartsTableWidget->cellWidget(1, i));
            if (lab)
                lab->clear();
        }
    }
    lapCompChart->setData(driverData);
    lapCompChart->repaint();
}
Пример #4
0
void FormGame::updateTankReborn()
{
    ITank* tank = (ITank*)sender();
    int index = _tanks.indexOf(tank);

    if(index > -1)
    {
        int index_of_player = _match_players.value(index);
        QLabel* label = findChild<QLabel*>(QString("_l_time_to_reborn_%1").arg(index_of_player));
        label->clear();
        label->hide();
    }
    if(tank == _tank)
    {
        updateTankView();
    }
}
Пример #5
0
QWidget *AppAboutPage::createPage(QWidget *parent)
{
    QWidget *w = new QWidget(parent);
    QVBoxLayout *layout = new QVBoxLayout(w);
    layout->setSpacing(0);
    layout->setMargin(0);

    // Splash label
    QWidget *sw = new QWidget(w);
    QHBoxLayout *swLayout = new QHBoxLayout(sw);
    sw->setLayout(swLayout);
    QLabel *splash = new QLabel(w);
    splash->setPixmap(theme()->splashScreenPixmap(settings()->path(Core::ISettings::SplashScreen)));
    splash->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
    swLayout->addSpacerItem(new QSpacerItem(10, 10, QSizePolicy::Expanding));
    swLayout->addWidget(splash);
    swLayout->addSpacerItem(new QSpacerItem(10, 10, QSizePolicy::Expanding));
    layout->addWidget(sw);
    QFrame *line = new QFrame(w);
    line->setFrameShape(QFrame::HLine);
    line->setFrameShadow(QFrame::Sunken);
    layout->addWidget(line);
    layout->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Fixed, QSizePolicy::Fixed));

    // Welcome label
    QLabel *label = new QLabel(w);
    label->setWordWrap(true);
    label->setOpenExternalLinks(true);
    layout->addWidget(label);
    layout->addSpacerItem(new QSpacerItem(20,20, QSizePolicy::Expanding, QSizePolicy::Expanding));
    label->clear();
        Utils::UpdateChecker *up = Core::ICore::instance()->updateChecker();
    QString tmp = tkTr(Trans::Constants::APPLICATION_ABOUT_YEAR_1_WEB_2)
                   .arg(QDate::currentDate().year())
                   .arg(qApp->organizationDomain());
    if (up->hasUpdate()) {
        tmp.append(tkTr(Trans::Constants::UPDATE_AVAILABLE));
    } else {
        tmp.append(tkTr(Trans::Constants::VERSION_UPTODATE));
    }
    label->setText(tmp);
    return w;
}
Пример #6
0
void LapTimeComparisonDialog::show(int currentCarId)
{
//    if (comboBox[0]->itemText(1) == "")
//    {
//        comboBox[0]->addItems(SeasonData::getInstance().getDriversList());
//        comboBox[1]->addItems(SeasonData::getInstance().getDriversList());
//        comboBox[2]->addItems(SeasonData::getInstance().getDriversList());
//        comboBox[3]->addItems(SeasonData::getInstance().getDriversList());
//    }
    setCurrentDriver(currentCarId);
    for (int i = 0; i < 4; ++i)
    {
        QLabel *lab = qobject_cast<QLabel*>(ui->tableWidget->cellWidget(0, i+1));
        if (lab)
            lab->clear();
    }

    updateData();
    updateCharts();

    QDialog::show();
}
Пример #7
0
QWidget *AppAboutPage::createPage(QWidget *parent)
{
    QWidget *w = new QWidget(parent);
    QVBoxLayout *layout = new QVBoxLayout(w);
    layout->setSpacing(0);
    layout->setMargin(0);
    QLabel *label = new QLabel(w);
    label->setWordWrap(true);
    label->setOpenExternalLinks(true);
    layout->addWidget(label);
    layout->addSpacerItem(new QSpacerItem(20,20, QSizePolicy::Expanding, QSizePolicy::Expanding));
    label->clear();
    Utils::UpdateChecker *up = Core::ICore::instance()->updateChecker();
    QString tmp = tr(ABOUT_TEXT).arg(qApp->applicationName(), qApp->organizationDomain()).arg(QDate::currentDate().year());
    if (up->hasUpdate()) {
        tmp.append("<br /><br />" + tkTr(Trans::Constants::UPDATE_AVAILABLE));
    } else {
        tmp.append("<br /><br />" + tkTr(Trans::Constants::VERSION_UPTODATE));
    }
    label->setText(tmp);
    return w;
}
/**
 * 五组原图显示函数
 */
bool ImageViewer::updateImages()
{
    if (!hasinitmodel)
        return false;

    QString tmpcamid;
    bool ret = true;
    QString tmpcamimgdir;

    QLabel * tmpcamimg1 = NULL;
    QLabel * tmpcamimg2 = NULL;
    QLabel * tmpcamimg3 = NULL;
    QLabel * tmpcamimg4 = NULL;
    QLabel * tmpcamimg5 = NULL;
    QLabel * tmpcamimg = NULL;
    tmphasfc1 = false;
    tmphasfc2 = false;
    tmphasfc3 = false;
    tmphasfc4 = false;
    tmphasfc5 = false;

    for (int i = 0; i < 5; i++)
    {
        switch (i)
        {
            case 0: tmpcamid = ui->cam1->currentText(); 
                tmpcamimg1 = ui->cam1img1;
                tmpcamimg2 = ui->cam1img2;
                tmpcamimg3 = ui->cam1img3;
                tmpcamimg4 = ui->cam1img4;
                tmpcamimg5 = ui->cam1img5;
                break;
            case 1: tmpcamid = ui->cam2->currentText(); 
                tmpcamimg1 = ui->cam2img1;
                tmpcamimg2 = ui->cam2img2;
                tmpcamimg3 = ui->cam2img3;
                tmpcamimg4 = ui->cam2img4;
                tmpcamimg5 = ui->cam2img5;
                break;
            case 2: tmpcamid = ui->cam3->currentText(); 
                tmpcamimg1 = ui->cam3img1;
                tmpcamimg2 = ui->cam3img2;
                tmpcamimg3 = ui->cam3img3;
                tmpcamimg4 = ui->cam3img4;
                tmpcamimg5 = ui->cam3img5;
                break;
            case 3: tmpcamid = ui->cam4->currentText(); 
                tmpcamimg1 = ui->cam4img1;
                tmpcamimg2 = ui->cam4img2;
                tmpcamimg3 = ui->cam4img3;
                tmpcamimg4 = ui->cam4img4;
                tmpcamimg5 = ui->cam4img5;
                break;
            case 4: tmpcamid = ui->cam5->currentText(); 
                tmpcamimg1 = ui->cam5img1;
                tmpcamimg2 = ui->cam5img2;
                tmpcamimg3 = ui->cam5img3;
                tmpcamimg4 = ui->cam5img4;
                tmpcamimg5 = ui->cam5img5;
                break;
            default:break;
        }

        __int64 & tmpcurrentfc = getTmpCurrentfc(i);

        if (tmpcamid.trimmed().compare("") == 0)
        {
            tmpcamimg1->clear();
            tmpcamimg2->clear();
            tmpcamimg3->clear();
            tmpcamimg4->clear();
            tmpcamimg5->clear();
            continue;
        }
        tmpcamimgdir = currenttmpimgpath + "_" + tmpcamid + "/";

        // 每个相机的5张图
        for (int j = -2; j < 3; j++)
        {
            switch (j)
            {
                case -2: tmpcamimg = tmpcamimg1; break;
                case -1: tmpcamimg = tmpcamimg2; break;
                case 0: tmpcamimg = tmpcamimg3; break;
                case 1: tmpcamimg = tmpcamimg4; break;
                case 2: tmpcamimg = tmpcamimg5; break;
                default:break;
            }

            QString filename3 = (QString("%1/%2.jpg").arg(tmpcamimgdir).arg(tmpcurrentfc + j));
            if (!QFile(filename3).exists())
            {
                // 清空显示
                tmpcamimg->clear();
                qDebug() << QObject::tr("图片目录:") << filename3 << QObject::tr("不存在!");

                ret = false;
                continue;
            }
            qDebug() << QObject::tr("图片目录:") << filename3;

            bool & tmphasfc = getTmphasfc(j + 2);
            tmphasfc = true;

            // 做图像增强处理
            QByteArray tmpba = filename3.toLocal8Bit();
            cv::Mat img = cv::imread(tmpba.constData(), CV_LOAD_IMAGE_GRAYSCALE);
            float sclae = 0.3; // 缩放比例
            cv::Size size = cv::Size(img.size().width * sclae, img.size().height * sclae);
            cv::resize(img, img, size);
            //cv::imshow("win1",img);
            //cv::waitKey(0);
            if (ifimgenhance == 2)
            {
                
                double alpha = 2;  
                double beta = 50; 

                // 调整对比度,RGB调整,速度慢
                /*
                result = Mat::zeros(img.size(),img.type()); 
                for (int i = 0;i<img.rows;++i)  
                    for(int j= 0;j<img.cols;++j)  
                        for (int k = 0; k < 3; k++)
                            result.at(i,j)[k] = cv::saturate_cast<uchar>(img.at(i,j)[k]*alpha+beta);  
                cv::cvtColor(result,result, CV_BGRA2GRAY);
                */

                // 调整对比度,灰度调整,速度快
                cv::Mat result = cv::Mat(size, CV_8U);
                for( int i=0;i<img.rows;i++)  
                {  
                    uchar* dataimg = img.ptr<uchar>(i);
                    uchar* dataresult = result.ptr<uchar>(i);  
                    for(int j=0;j<img.cols;j++)  
                    {  
                        dataresult[j] = cv::saturate_cast<uchar>(dataimg[j]*alpha+beta);   
                    }  
                } 
                bigpm = MatToQImage(result);
            
                // 直方图均衡化---效果较差
                //cv::equalizeHist(img, result);
                //cv::imwrite("D:\\2.png", result);
                //cv::imshow("win1",result);
                //cv::waitKey(0);
            }
            else if (ifimgenhance == 1)
            {
                // 直方图规定化处理---By Ding
                cv::Mat result;
                LzCalculator::argument(img, result); 
                //cv::GaussianBlur(result, result, Size(5,5), 1.5, 1.5);
                bigpm = MatToQImage(result);
            }
            else
            {
                bigpm = MatToQImage(img);
            }
            
            smallpm = bigpm.scaled(TN_WIDTH, TN_HEIGHT, Qt::KeepAspectRatio);
            tmpcamimg->setPixmap(QPixmap::fromImage(smallpm));
            tmpcamimg->show();
        }
    }

    qDebug() << "has fc?: " << tmphasfc1 << tmphasfc2 << tmphasfc3 << tmphasfc4 << tmphasfc5;

    QLabel * tmpfclabel = NULL;
    QLabel * tmpmilelabel = NULL;

    // 每个相机的masterfc号
    for (int j = -2; j < 3; j++)
    {
        switch (j)
        {
            case -2: tmpfclabel = ui->fc1; tmpmilelabel = ui->mile1; break;
            case -1: tmpfclabel = ui->fc2; tmpmilelabel = ui->mile2; break;
            case 0: tmpfclabel = ui->fc3; tmpmilelabel = ui->mile3; break;
            case 1: tmpfclabel = ui->fc4; tmpmilelabel = ui->mile4; break;
            case 2: tmpfclabel = ui->fc5; tmpmilelabel = ui->mile5; break;
            default:break;
        }
        bool & tmphasfc = getTmphasfc(j + 2);
        if (tmphasfc)
        {
            tmpfclabel->setText(QString("%1").arg(current_fc_master + j));
            tmpmilelabel->setText(QString("%1").arg(current_fc_master + j));
        }
        else
        {
            tmpfclabel->setText(QString("%1无数据").arg(current_fc_master + j));
            tmpmilelabel->setText(QString("%1无数据").arg(current_fc_master + j));
        }
    }

    // 强制更新显示
    this->repaint();
    
    return ret;
}
Пример #9
0
void LapTimeComparisonDialog::updateData()
{
    int scrollBarPosition = ui->tableWidget->verticalScrollBar()->sliderPosition();

    QItemSelectionModel * selection = ui->tableWidget->selectionModel();
//    for (int i = ui->tableWidget->rowCount()-1; i >= 0; --i)
//        ui->tableWidget->removeRow(i);

    QTableWidgetItem *item;

    int firstLap = 99, lastLap = 0;
    int index[4];

    QString wTitle = "Lap time comparison: ";
    for (int i = 0; i < 4; ++i)
    {
        index[i] = 0;
        int idx = eventData.getDriverId(getNumber(i));
        if (idx > 0)
        {
            if (i > 0)
                wTitle += " - ";
            wTitle += eventData.getDriversData()[idx-1].getDriverName();
            if(!eventData.getDriversData()[idx-1].getLapData().isEmpty())
            {
                if (eventData.getDriversData()[idx-1].getLapData()[0].getLapNumber() < firstLap)
                    firstLap = eventData.getDriversData()[idx-1].getLapData()[0].getLapNumber();

                if (eventData.getDriversData()[idx-1].getLapData().last().getLapNumber() > lastLap)
                    lastLap = eventData.getDriversData()[idx-1].getLapData().last().getLapNumber();
            }

            DriverData &dd = eventData.getDriversData()[idx-1];
			QLabel *lab = qobject_cast<QLabel*>(ui->tableWidget->cellWidget(0, i+1));
            lab->setPixmap(ImagesFactory::getInstance().getCarThumbnailsFactory().getCarThumbnail(dd.getNumber(), thumbnailsSize));//eventData.carImages[idx].scaledToWidth(120, Qt::SmoothTransformation));
        }
        else
        {
        	QLabel *lab = qobject_cast<QLabel*>(ui->tableWidget->cellWidget(0, i+1));
        	lab->clear();
        }
    }
    setWindowTitle(wTitle);

//    ui->tableWidget->insertRow(0);
//    ui->tableWidget->setRowHeight(0, 50);

    int j = 0, k = firstLap;
    for (; k <= lastLap; ++k, ++j)
    {
        int lapNo = lastLap - k + firstLap;
        LapTime laps[4];

        if (ui->tableWidget->rowCount() <= j+1)
            ui->tableWidget->insertRow(j+1);

        item = ui->tableWidget->item(j+1, 0);
        if (!item)
        {
            item = new QTableWidgetItem(QString("%1.").arg(lapNo));
//                item->setFlags(Qt::ItemIsSelectable);
            item->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
            item->setTextColor(ColorsManager::getInstance().getColor(LTPackets::DEFAULT));
            ui->tableWidget->setItem(j+1, 0, item);
        }
        else
            item->setText(QString("%1.").arg(lapNo));


        for (int i = 0; i < 4; ++i)
        {
            int idx = eventData.getDriverId(getNumber(i));

            if (idx > 0 && !eventData.getDriversData()[idx-1].getLapData().isEmpty())
            {
                //int lapIndex = (reversedOrder ? eventData.driversData[idx-1].lapData.size() - index[i] - 1 : index[i]);
                DriverData &dd = eventData.getDriversData()[idx-1];
                LapData ld = dd.getLapData(lapNo);

//                if (j == 0)
//                {
//                    int idx = (dd.number > 13 ? dd.number-2 : dd.number-1) / 2;
//                    QLabel *lab = qobject_cast<QLabel*>(ui->tableWidget->cellWidget(0, i+1));
//                    lab->setPixmap(smallCarImg[idx]);//eventData.carImages[idx].scaledToWidth(120, Qt::SmoothTransformation));
//                }

                if (dd.getLapData().size() > index[i] && ld.getLapNumber() == lapNo && ld.getCarID() != -1)
                {
                    laps[i] = ld.getTime();

                    item = ui->tableWidget->item(j+1, i+1);
                    if (!item)
                    {
                        item = new QTableWidgetItem(ld.getTime());
                        item->setTextAlignment(Qt::AlignCenter);
                        ui->tableWidget->setItem(j+1, i+1, item);
                    }
                    else
                        item->setText(ld.getTime());

                    if (ld.getTime().toString() == "IN PIT")
                        item->setText(item->text() + " (" + dd.getPitTime(ld.getLapNumber()) + ")");

                    ++index[i];
                }
                else
                {
                    item = ui->tableWidget->item(j+1, i+1);
                    if (item)
                        item->setText("");
                }
            }
            else
            {
                if (j == 0)
                {
//                    QLabel *lab = qobject_cast<QLabel*>(ui->tableWidget->cellWidget(0, i+1));
//                    if (lab)
//                        lab->clear();
                }
                item = ui->tableWidget->item(j+1, i+1);
                if (item)
                    item->setText("");
            }
        }
        int bestIdx = DriverData::lapDiff(laps);
        if (bestIdx != -1)
        {
            for (int i = 0; i < 4; ++i)
            {
                if (i != bestIdx && laps[i].toString() != "" && laps[i].toString() != "IN PIT" && laps[i].toString() != "RETIRED" && !laps[i].toString().contains("LAP"))
                {
                    item = ui->tableWidget->item(j+1, i+1);

                    if (item)
                    {
                       item->setText(item->text() + " (+"+QString::number(laps[i].toDouble(), 'f', 3)+")");

                        double msecs[3];
                        int ji = 0;

                        for (int j = 0; j < 4; ++j)
                        {
                            if (j != bestIdx)
                            {
                                if (laps[j].toString() != "")
                                    msecs[ji++] = laps[j].toMsecs();
                                else
                                    msecs[ji++] = 1000000;
                            }
                        }
                        double maxGap = std::max(std::max(msecs[0], msecs[1]), msecs[2]);
                        double minGap = std::min(std::min(msecs[0], msecs[1]), msecs[2]);

                        LTPackets::Colors color = LTPackets::YELLOW;

                        if (laps[i].toMsecs() == minGap)
                            color = LTPackets::WHITE;

                        else if (laps[i].toMsecs() == maxGap)
                            color = LTPackets::RED;

                        item->setTextColor(ColorsManager::getInstance().getColor(color));
                    }
                }
                else if (laps[i].toString() == "IN PIT" || laps[i].toString() == "RETIRED" ||  laps[i].toString().contains("LAP"))
                {
                    item = ui->tableWidget->item(j+1, i+1);
                    item->setTextColor(ColorsManager::getInstance().getColor(LTPackets::RED));
                }
            }
            item = ui->tableWidget->item(j+1, bestIdx+1);
            if (item && laps[bestIdx].toString() != "IN PIT" && laps[bestIdx].toString() != "RETIRED" && !laps[bestIdx].toString().contains("LAP"))
                item->setTextColor(ColorsManager::getInstance().getColor(LTPackets::GREEN));
        }
        ui->tableWidget->setRowHeight(j+1, 20);
    }
    for (int i = ui->tableWidget->rowCount()-1; i >= j+1; --i)
        ui->tableWidget->removeRow(i);

    ui->tableWidget->setSelectionModel(selection);
    ui->tableWidget->verticalScrollBar()->setSliderPosition(scrollBarPosition);
}
Пример #10
0
int main(int argc, char **argv)
{
	Vals vals;

	/* the application */
	QApplication app(argc, argv);
	app.setApplicationName(APP_NAME);
	app.setWindowIcon(QIcon(":/icon"));
	Window window;

	/* translations */
	QTranslator qtr;
	if (qtr.load("qt_" + QLocale::system().name(), QTR_PATH))
		app.installTranslator(&qtr);

	QTranslator htr;
	if (htr.load("H4KvT_" + QLocale::system().name(), ":/"))
		app.installTranslator(&htr);

	/* display information */
	QTextEdit *text = new QTextEdit;
	text->setReadOnly(true);
	text->setLineWrapMode(QTextEdit::NoWrap);
	text->setToolTip(Window::tr("Drop any file for hashing"));
	QObject::connect(&window, &Window::idle, text, &QWidget::setEnabled);

	/* compare hash */
	QLineEdit *test = new QLineEdit;
	HexVal hexval;
	test->setValidator(&hexval);
	test->installEventFilter(&window);
	test->setToolTip(Window::tr("Compare hashes"));

	QObject::connect(test, &QLineEdit::textChanged,
		[&](const QString &newValue) { if (vals.name != "") {
			std::string hashVal = newValue.toStdString();
			std::transform(hashVal.begin(), hashVal.end(), hashVal.begin(), ::tolower);
			std::stringstream html;
			if (hashVal != "")
				html << "<style>.h" << hashVal << "{color:green}</style>";
			html << "<div style='margin-bottom:2; font-size:27px'><i><b>" << vals.name << "</b></i></div>";
			html << "<div style='margin-bottom:7; margin-left:23; font-size:13px'>" << vals.path << "</div>";
			if (!ALL(vals,"")) {
				html << "<div style='font-size:13px'><table>";
				if (vals.md5 != "")
					html << "<tr><td>md5: </td><td class='h" << vals.md5 << "'>" << vals.md5 << "</td</tr>";
				if (vals.sha1 != "")
					html << "<tr><td>sha1: </td><td class='h" << vals.sha1 << "'>" << vals.sha1 << "</td</tr>";
				if (vals.sha224 != "")
					html << "<tr><td>sha224: </td><td class='h" << vals.sha224 << "'>" << vals.sha224 << "</td</tr>";
				if (vals.sha256 != "")
					html << "<tr><td>sha256: </td><td class='h" << vals.sha256 << "'>" << vals.sha256 << "</td</tr>";
				if (vals.sha384 != "")
					html << "<tr><td>sha384: </td><td class='h" << vals.sha384 << "'>" << vals.sha384 << "</td</tr>";
				if (vals.sha512 != "")
					html << "<tr><td>sha512: </td><td class='h" << vals.sha512 << "'>" << vals.sha512 << "</td</tr>";
				html << "</table></div>";
			}
			int horizontal = text->horizontalScrollBar()->value();
			int vertical = text->verticalScrollBar()->value();
			text->setHtml(QString::fromStdString(html.str()));
			text->horizontalScrollBar()->setValue(horizontal);
			text->verticalScrollBar()->setValue(vertical);
			test->setStyleSheet(ANY(vals,hashVal) ? "color:green" : "");
		}});

	/* error messages */
	QLabel *error = new QLabel;
	error->setStyleSheet("color:red");

	/* test or error */
	QStackedWidget *stack = new QStackedWidget;
	delete stack->layout();
	stack->setLayout(new Stack);
	stack->addWidget(error);
	stack->addWidget(test);
	stack->setCurrentIndex(1);

	/* toggle test or error */
	QPushButton *hash = new QPushButton(QIcon(":/icon"), "");
	hash->setCheckable(true);
	hash->setChecked(true);
	hash->setToolTip(Window::tr("Compare hashes"));
	QObject::connect(hash, &QPushButton::toggled, stack, &QStackedWidget::setCurrentIndex);

	/* store method */
	QSettings settings("H4KvT", "H4KvT");

	/* more methods */
	bool more;
	try {
		settings.setValue("MoreHashingMethods", more = moreOrLess());
	} catch (...) {
		more = settings.value("MoreHashingMethods", false).toBool();
	}

	/* hashing method */
	QComboBox *meth = new QComboBox;
	meth->addItem("md5");
	meth->addItem("sha1");
	if (more) meth->addItem("sha224");
	meth->addItem("sha256");
	if (more) meth->addItem("sha384");
	meth->addItem("sha512");
	meth->setToolTip(Window::tr("Hashing method"));
	meth->setCurrentText(settings.value("HashingMethod", "md5").toString());
	QObject::connect(&window, &Window::idle, meth, &QWidget::setEnabled);

	QObject::connect(meth, &QComboBox::currentTextChanged,
		[&](const QString &text) { settings.setValue("HashingMethod", text); });

	/* toolbar */
	QHBoxLayout *pane = new QHBoxLayout;
	pane->addWidget(hash, 0, Qt::AlignLeft);
	pane->addWidget(stack);
	pane->addWidget(meth, 0, Qt::AlignRight);

	/* main layout */
	QVBoxLayout *layout = new QVBoxLayout;
	layout->addWidget(text);
	layout->addLayout(pane);

	/* the window */
	window.centralWidget()->setLayout(layout);
	window.show();

	/* future hashing */
	QFutureWatcher<Vals> zu;
	QObject::connect(&zu, &QFutureWatcher<Vals>::finished,
		[&]() {
			Vals valsi = zu.future().result();
			window.idle(true);
			if (valsi.path == "") {
				error->setText(QString::fromStdString(valsi.name));
				hash->setChecked(false);
			} else {
				error->clear();
				vals += valsi;
				test->textChanged(test->text());
			}
		});

	QObject::connect(meth, &QComboBox::currentTextChanged,
		[&](const QString &text) { if (vals.name != "") {
			window.idle(false);
			zu.setFuture(QtConcurrent::run(&update, text, vals));
		}});

	QObject::connect(&window, &Window::fileDroped,
		[&](const QString &name, const QString &path) {
			window.idle(false);
			zu.setFuture(QtConcurrent::run(&update, meth->currentText(), Vals(name, path)));
		});

	/* hashing info */
	QGraphicsBlurEffect blur;
	blur.setBlurHints(QGraphicsBlurEffect::AnimationHint);

	QPropertyAnimation anim(&blur, "blurRadius");
	anim.setDuration(2000);
	anim.setLoopCount(-1);
	anim.setKeyValueAt(0, 0);
	anim.setKeyValueAt(0.5, 3);
	anim.setKeyValueAt(1, 0);

	QLabel *hashing = new QLabel;
	hashing->setPixmap(QPixmap(":/icon"));
	hashing->setAttribute(Qt::WA_TransparentForMouseEvents);
	hashing->setGraphicsEffect(&blur);
	hashing->hide();
	(new QHBoxLayout(text))->addWidget(hashing, 0, Qt::AlignCenter);

	QObject::connect(&blur, &QGraphicsBlurEffect::blurRadiusChanged,
		hashing, static_cast<void(QWidget::*)()>(&QWidget::update));

	QObject::connect(&window, &Window::idle,
		[&](bool idle) {
			if (idle) {
				hashing->hide();
				anim.stop();
			} else {
				hashing->show();
				anim.start();
			}
		});

	/* about app */
	QMenu about;
	QAction *action = about.addAction(QIcon(":/icon"), Window::tr("About %1").arg(APP_NAME));
	action->setMenuRole(QAction::AboutRole);
	QObject::connect(action, &QAction::triggered, &window, &Window::about);

	error->setContextMenuPolicy(Qt::NoContextMenu);
	hash->setContextMenuPolicy(Qt::NoContextMenu);
	meth->setContextMenuPolicy(Qt::NoContextMenu);
	window.setContextMenuPolicy(Qt::CustomContextMenu);
	QObject::connect(&window, &QWidget::customContextMenuRequested,
		[&about, &window](const QPoint &pos) { about.popup(window.mapToGlobal(pos)); });

	text->setContextMenuPolicy(Qt::CustomContextMenu);
	QObject::connect(text, &QWidget::customContextMenuRequested,
		[action, text](const QPoint &pos) {
			if (QMenu *m = text->createStandardContextMenu()) {
				m->insertAction(m->insertSeparator(m->actions()[0]), action);
				m->popup(text->mapToGlobal(pos));
			}
		});

	test->setContextMenuPolicy(Qt::CustomContextMenu);
	QObject::connect(test, &QWidget::customContextMenuRequested,
		[action, test](const QPoint &pos) {
			if (QMenu *m = test->createStandardContextMenu()) {
				m->insertAction(m->insertSeparator(m->actions()[0]), action);
				m->popup(test->mapToGlobal(pos));
			}
		});

	return app.exec();
}