#include #include #include #include "client.h" #include "UpdatedConfig.h" #include "Dialog.h" #include "Proxifier.h" #include "Proxy.h" using namespace std; ProxyDialog::ProxyDialog(QWidget *parent): QDialog(parent, Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint) { UpdatedConfig *cfg = UpdatedConfig::CurrentConfig(); Proxifier *proxifier = Proxifier::GetInstance(); if (!proxifier->IsValid()) { Logger::Error("No valid proxifier configuration file found!\n"); } /* generic proxy panel */ topLabel = new QLabel(QString::fromLocal8Bit(cfg->TopPanelText.c_str())); topLabel->setObjectName("topLabel"); topLabel->setAlignment(Qt::AlignHCenter); countryBox = new QComboBox; stateBox = new QComboBox; stateBox->setVisible(false); cityBox = new QComboBox; cityBox->setVisible(false); vector countries = cfg->GetCountries(); for (unsigned i = 0; i < countries.size(); i++) { QString country = QString::fromLocal8Bit(countries[i].c_str()); countryBox->addItem(country); } countryBox->setCurrentIndex(-1); connect(countryBox, SIGNAL(activated(int)), this, SLOT(CountryActivated(int))); connect(stateBox, SIGNAL(activated(int)), this, SLOT(StateActivated(int))); connect(cityBox, SIGNAL(activated(int)), this, SLOT(CityActivated(int))); topPanelLayout = new QGridLayout; topPanelLayout->setSpacing(5); topPanelLayout->addWidget(countryBox, 0, 0); topPanelLayout->addWidget(stateBox, 1, 0); topPanelLayout->addWidget(cityBox, 2, 0); genericProxyGroup = new QButtonGroup; staticProxyGroup = new QButtonGroup; // static proxy panel bottomLabel = new QLabel(QString::fromLocal8Bit(cfg->BottomPanelText.c_str())); bottomLabel->setObjectName("bottomLabel"); bottomLabel->setAlignment(Qt::AlignHCenter); QGridLayout *bottomPanelLayout = new QGridLayout; unsigned nlines = cfg->GetStaticProxyGuiLines(); for (unsigned i = 0; i < nlines; i++) { vector staticProxyLine = cfg->GetStaticProxyGuiLine(i+1); for (unsigned j = 0; j < staticProxyLine.size(); j++) { QString btnStr; if (cfg->IsSpeedVisible) { double speed = 1.0 * staticProxyLine[j].speed * 8 / 1000000; if (staticProxyLine[j].speed > cfg->StaticProxySpeedLow) { btnStr = QString("") + QString::number(speed, 'f', 3) + QString(""); } else if (staticProxyLine[j].speed > cfg->StaticProxySpeedLowCrucial) { btnStr = QString("") + QString::number(speed, 'f', 3) + QString(""); } else { btnStr = QString("") + QString::number(speed, 'f', 3) + QString(""); } btnStr += " "; } btnStr += QString::fromLocal8Bit(staticProxyLine[j].name.c_str()); QLabel *btnLabel = new QLabel(btnStr); btnLabel->setAttribute(Qt::WA_TransparentForMouseEvents); QHBoxLayout *btnLayout = new QHBoxLayout; // insert spacers at the beginning and // the end to center-align button content btnLayout->addStretch(); btnLayout->addWidget(btnLabel); btnLayout->setSizeConstraint(QLayout::SetMinimumSize); btnLayout->addStretch(); QPushButton *btn = new QPushButton(); btn->setObjectName("bottomBtn"); btn->setCheckable(true); if (proxifier->IsValid()) { btn->setChecked(proxifier->IsOn(staticProxyLine[j].host, staticProxyLine[j].port)); } else { btn->setChecked(false); } btn->setProperty("proxyName", QString::fromLocal8Bit(staticProxyLine[j].name.c_str())); btn->setLayout(btnLayout); connect(btn, SIGNAL(toggled(bool)), this, SLOT(StaticProxyToggled(bool))); staticProxyGroup->addButton(btn); bottomPanelLayout->addWidget(btn, i, j); } } /* setup layouting */ QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addWidget(topLabel); mainLayout->addLayout(topPanelLayout); mainLayout->addWidget(bottomLabel); mainLayout->addLayout(bottomPanelLayout); setLayout(mainLayout); } bool ProxyDialog::event(QEvent* event) { if (event->type() == QEvent::ActivationChange) { if(QApplication::activeWindow() != this) { this->close(); } } return QDialog::event(event); } void ProxyDialog::resizeEvent(QResizeEvent* event) { QRect availScreenRect = QApplication::desktop()->availableGeometry(); this->move(availScreenRect.width() - this->frameSize().width(), availScreenRect.height() - this->frameSize().height()); } void ProxyDialog::ProxyToggled(bool on) { QPushButton* btn = (QPushButton*) sender(); QVariant propVal; propVal = btn->property("proxyHost"); QString proxyHost = propVal.toString(); propVal = btn->property("proxyPort"); short port = (short)propVal.toUInt(); Logger::Debug("Proxy button toggled\n"); Logger::Debug("State '%s', associated proxy: %s:%u\n", on ? "down" : "up", proxyHost.toStdString().c_str(), port); UpdatedConfig *cfg = UpdatedConfig::CurrentConfig(); string host = proxyHost.toStdString(); ProxyEntryGeneric* proxy = cfg->GetGenericProxy(host, port); if (proxy == NULL) { Logger::Error("Generic proxy %s:%u was not found\n", host.c_str(), port); return; } Proxifier *proxifier = Proxifier::GetInstance(); if (!proxifier->IsValid()) { Logger::Fatal("No valid proxifier configuration file found!\n"); } if (on) { vector active = proxifier->GetActiveProxies(); // check if we are going to add another http/https proxy if (active.size() != 0) { bool isHttp = (stricmp(proxy->type.c_str(), "http") == 0); for (unsigned i = 0; i < active.size(); i++) { if (isHttp && (stricmp(active[i].type.c_str(), "http") == 0)) { QMessageBox otherHttpProxy; otherHttpProxy.setText("Two HTTP proxy in one chain are not allowed"); otherHttpProxy.setWindowTitle("Information"); otherHttpProxy.setStandardButtons(QMessageBox::Ok); otherHttpProxy.setIcon(QMessageBox::Information); otherHttpProxy.exec(); return; } } } for (unsigned i = 0; i < active.size(); i++) { ProxyEntryGeneric* genProxy = cfg->GetGenericProxy(active[i].host, active[i].port); if (genProxy == NULL) { continue; } proxifier->TurnProxyOff(*genProxy); } proxifier->TurnProxyOn(*proxy); } } void ProxyDialog::StaticProxyToggled(bool on) { QPushButton* btn = (QPushButton*) sender(); QVariant propVal = btn->property("proxyName"); QString proxyName = propVal.toString(); Logger::Debug("Static Proxy button toggled\n"); Logger::Debug("State '%s', associated proxy name: %s\n", on ? "down" : "up", proxyName.toLocal8Bit().data()); if (!on) { return; } UpdatedConfig *cfg = UpdatedConfig::CurrentConfig(); string name = proxyName.toLocal8Bit().data(); ProxyEntryStatic* proxy = cfg->GetStaticProxy(name); if (proxy == NULL) { Logger::Error("Static proxy with name '%s' was not found\n", proxyName.toLocal8Bit().data()); return; } Proxifier *proxifier = Proxifier::GetInstance(); if (!proxifier->IsValid()) { Logger::Fatal("No valid proxifier configuration file found!\n"); } // check if we are going to add another http proxy vector active = proxifier->GetActiveProxies(); if (active.size() != 0) { for (unsigned i = 0; i < active.size(); i++) { proxifier->TurnProxyOff(active[i]); } } proxifier->TurnProxyOn(*proxy); } void ProxyDialog::CountryActivated(int index) { Logger::Trace("Country activated. Activated index=%d\n", index); stateBox->setVisible(false); cityBox->setVisible(false); if (index == -1) { return; } string country(countryBox->currentText().toLocal8Bit().constData()); Logger::Info("Country %s was selected\n", country.c_str()); UpdatedConfig *cfg = UpdatedConfig::CurrentConfig(); vector states = cfg->GetStates(country); if (states.empty()) { Logger::Info("There are no states in %s\n",country.c_str()); vector cities = cfg->GetCities(country); cityBox->clear(); for (unsigned i = 0; i < cities.size(); i++) { QString city = QString::fromLocal8Bit(cities[i].c_str()); cityBox->addItem(city); } cityBox->setCurrentIndex(-1); cityBox->adjustSize(); cityBox->setVisible(true); } else { stateBox->clear(); for (unsigned i = 0; i < states.size(); i++) { QString state = QString::fromLocal8Bit(states[i].c_str()); stateBox->addItem(state); } stateBox->setCurrentIndex(-1); stateBox->adjustSize(); stateBox->setVisible(true); } } void ProxyDialog::StateActivated(int index) { Logger::Trace("State activated. Activated index=%d\n", index); cityBox->setVisible(false); if (index == -1) { return; } string country(countryBox->currentText().toLocal8Bit().constData()); string state(stateBox->currentText().toLocal8Bit().constData()); Logger::Info("State %s was selected\n", state.c_str()); UpdatedConfig *cfg = UpdatedConfig::CurrentConfig(); vector cities = cfg->GetCities(country, state); cityBox->clear(); for (unsigned i = 0; i < cities.size(); i++) { QString city = QString::fromLocal8Bit(cities[i].c_str()); cityBox->addItem(city); } cityBox->setCurrentIndex(-1); cityBox->adjustSize(); cityBox->setVisible(true); } void ProxyDialog::CityActivated(int index) { Logger::Trace("City activated. Activated index=%d\n", index); if (index == -1) { return; } vector proxies; UpdatedConfig *cfg = UpdatedConfig::CurrentConfig(); string country(countryBox->currentText().toLocal8Bit().constData()); string city(cityBox->currentText().toLocal8Bit().constData()); if (stateBox->isVisible()) { string state(stateBox->currentText().toLocal8Bit().constData()); proxies = cfg->GetProxies(country, state, city); } else { proxies = cfg->GetProxies(country, city); } /* delete existing buttons */ if (topPanelLayout->count() != 0) { Logger::Trace("Going to delete existing buttons\n"); QLayoutItem *child; while ((child = topPanelLayout->takeAt(3)) != 0) { delete child->widget(); } } Logger::Trace("Adding new buttons\n"); Proxifier *proxifier = Proxifier::GetInstance(); if (!proxifier->IsValid()) { Logger::Fatal("No valid proxifier configuration file found!\n"); return; } for (unsigned i = 0; i < proxies.size(); i++) { QString btnStr = QString::fromLocal8Bit(proxies[i].host.c_str()); QPushButton *btn = new QPushButton(btnStr); btn->setCheckable(true); btn->setChecked(proxifier->IsOn(proxies[i].host, proxies[i].port)); btn->setProperty("proxyHost", QString::fromLocal8Bit(proxies[i].host.c_str())); btn->setProperty("proxyPort", proxies[i].port); connect(btn, SIGNAL(toggled(bool)), this, SLOT(ProxyToggled(bool))); genericProxyGroup->addButton(btn); topPanelLayout->addWidget(btn, i / 3, i % 3 + 1); } }