#include "server_config_dialog.h" #include #include #include #include #include #include #include #include #include #include #include #include "startup.h" #include "yacreader_global_gui.h" #include "qnaturalsorting.h" #include // 192.168 (most comon local subnet for ips are always put first) // IPs are sorted using natoral sorting bool ipComparator(const QString &ip1, const QString &ip2) { if (ip1.startsWith("192.168") && ip2.startsWith("192.168")) return naturalSortLessThanCI(ip1, ip2); if (ip1.startsWith("192.168")) return true; if (ip2.startsWith("192.168")) return false; return naturalSortLessThanCI(ip1, ip2); } #ifndef Q_OS_WIN32 #include #include #include #include #include #include QList addresses() { struct ifaddrs *ifAddrStruct = NULL; struct ifaddrs *ifa = NULL; void *tmpAddrPtr = NULL; QList localAddreses; getifaddrs(&ifAddrStruct); for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) { if (ifa->ifa_addr) { if (ifa->ifa_addr->sa_family == AF_INET) { // check it is IP4 // is a valid IP4 Address tmpAddrPtr = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr; char addressBuffer[INET_ADDRSTRLEN]; inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN); localAddreses.push_back(QString(addressBuffer)); // printf("%s IP Address %s\n", ifa->ifa_name, addressBuffer); } else if (ifa->ifa_addr->sa_family == AF_INET6) { // check it is IP6 // is a valid IP6 Address tmpAddrPtr = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr; char addressBuffer[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, INET6_ADDRSTRLEN); // printf("%s IP Address %s\n", ifa->ifa_name, addressBuffer); } } } if (ifAddrStruct != NULL) freeifaddrs(ifAddrStruct); return localAddreses; } #endif extern Startup *s; ServerConfigDialog::ServerConfigDialog(QWidget *parent) : QDialog(parent) { accept = new QPushButton(tr("set port"), this); qrCode = new QLabel(this); qrCode->move(64, 112); qrCode->setFixedSize(200, 200); qrCode->setScaledContents(true); QLabel *title1 = new QLabel(tr("Server connectivity information"), this); title1->move(332, 61); title1->setStyleSheet("QLabel {color:#474747; font-size:30px; font-family: Arial;}"); QLabel *qrMessage = new QLabel(tr("Scan it!"), this); qrMessage->move(135, 388); // 373,627); qrMessage->setStyleSheet("QLabel {color:#A3A3A3; font-size:18px; font-family: Arial;}"); qrMessage->setWordWrap(true); qrMessage->setFixedWidth(200); QLabel *propaganda = new QLabel(tr("YACReader is available for iOS devices. Discover it! "), this); propaganda->move(332, 505); propaganda->setStyleSheet("QLabel {color:#4D4D4D; font-size:13px; font-family: Arial; font-style: italic;}"); /*propaganda->setWordWrap(true); propaganda->setFixedWidth(590);*/ propaganda->setOpenExternalLinks(true); // FORM--------------------------------------------------------------------- QLabel *ipLabel = new QLabel(tr("Choose an IP address"), this); ipLabel->move(332, 117); ipLabel->setStyleSheet("QLabel {color:#575757; font-size:18px; font-family: Arial;}"); QLabel *portLabel = new QLabel(tr("Port"), this); portLabel->move(332, 211); portLabel->setStyleSheet("QLabel {color:#575757; font-size:18px; font-family: Arial;}"); ip = new QComboBox(this); connect(ip, QOverload::of(&QComboBox::activated), this, &ServerConfigDialog::regenerateQR); ip->setFixedWidth(200); ip->move(332, 153); port = new QLineEdit("8080", this); port->setReadOnly(false); // port->setFixedWidth(100); // port->move(332, 244); // port->move(520,110); QValidator *validator = new QIntValidator(1024, 65535, this); port->setValidator(validator); QWidget *portWidget = new QWidget(this); auto portWidgetLayout = new QHBoxLayout(this); portWidgetLayout->addWidget(port); portWidgetLayout->addWidget(accept); portWidgetLayout->setContentsMargins(0, 0, 0, 0); portWidget->setLayout(portWidgetLayout); portWidget->move(332, 244); // accept->move(514,149); connect(accept, &QAbstractButton::pressed, this, &ServerConfigDialog::updatePort); // END FORM----------------------------------------------------------------- check = new QCheckBox(this); check->move(332, 314); check->setText(tr("enable the server")); check->setStyleSheet("QCheckBox {color:#262626; font-size:13px; font-family: Arial;}"); performanceWorkaroundCheck = new QCheckBox(this); performanceWorkaroundCheck->move(332, 354); performanceWorkaroundCheck->setText(tr("display less information about folders in the browser\nto improve the performance")); performanceWorkaroundCheck->setStyleSheet("QCheckBox {color:#262626; font-size:13px; font-family: Arial;}"); // set black background QPalette palette; QImage image(":/images/serverConfigBackground.png"); palette.setBrush(this->backgroundRole(), QBrush(image)); setPalette(palette); this->setFixedSize(image.size()); QSettings *settings = new QSettings(YACReader::getSettingsPath() + "/YACReaderLibrary.ini", QSettings::IniFormat); // TODO unificar la creación del fichero de config con el servidor settings->beginGroup("libraryConfig"); if (settings->value(SERVER_ON, true).toBool()) { check->setChecked(true); generateQR(); } else check->setChecked(false); performanceWorkaroundCheck->setChecked(settings->value(REMOTE_BROWSE_PERFORMANCE_WORKAROUND, false).toBool()); settings->endGroup(); connect(check, &QCheckBox::stateChanged, this, &ServerConfigDialog::enableServer); connect(performanceWorkaroundCheck, &QCheckBox::stateChanged, this, &ServerConfigDialog::enableperformanceWorkaround); } void ServerConfigDialog::enableServer(int status) { QSettings *settings = new QSettings(YACReader::getSettingsPath() + "/YACReaderLibrary.ini", QSettings::IniFormat); // TODO unificar la creación del fichero de config con el servidor settings->beginGroup("libraryConfig"); if (status == Qt::Checked) { s->start(); this->generateQR(); settings->setValue(SERVER_ON, true); } else { s->stop(); qrCode->setPixmap(QPixmap()); ip->clear(); port->setText(""); settings->setValue(SERVER_ON, false); } settings->endGroup(); } void ServerConfigDialog::enableperformanceWorkaround(int status) { QSettings *settings = new QSettings(YACReader::getSettingsPath() + "/YACReaderLibrary.ini", QSettings::IniFormat); // TODO unificar la creación del fichero de config con el servidor settings->beginGroup("libraryConfig"); if (status == Qt::Checked) { settings->setValue(REMOTE_BROWSE_PERFORMANCE_WORKAROUND, true); } else { settings->setValue(REMOTE_BROWSE_PERFORMANCE_WORKAROUND, false); } settings->endGroup(); } void ServerConfigDialog::generateQR() { ip->clear(); QString dir; #ifdef Q_OS_WIN32 QList list = QHostInfo::fromName(QHostInfo::localHostName()).addresses(); QList otherAddresses; foreach (QHostAddress add, list) { QString tmp = add.toString(); if (tmp.contains(".") && !tmp.startsWith("127")) { otherAddresses.push_back(tmp); } } #else QList list = addresses(); QList otherAddresses; foreach (QString add, list) { QString tmp = add; if (tmp.contains(".") && !tmp.startsWith("127")) { otherAddresses.push_back(tmp); } } #endif std::sort(otherAddresses.begin(), otherAddresses.end(), ipComparator); if (!otherAddresses.isEmpty()) { dir = otherAddresses.first(); otherAddresses.pop_front(); } if (otherAddresses.length() > 0 || !dir.isEmpty()) { if (!dir.isEmpty()) { generateQR(dir + ":" + s->getPort()); ip->addItem(dir); } else { generateQR(otherAddresses.first() + ":" + s->getPort()); } ip->addItems(otherAddresses); port->setText(s->getPort()); } } void ServerConfigDialog::generateQR(const QString &serverAddress) { qrCode->clear(); QrEncoder encoder; QBitmap image = encoder.encode(serverAddress); if (image.isNull()) { qrCode->setText(tr("Could not load libqrencode.")); } else { image = image.scaled(qrCode->size() * devicePixelRatio()); QPixmap pMask(image.size()); pMask.fill(QColor(66, 66, 66)); pMask.setMask(image.createMaskFromColor(Qt::white)); pMask.setDevicePixelRatio(devicePixelRatio()); qrCode->setPixmap(pMask); } } void ServerConfigDialog::regenerateQR(const QString &ip) { generateQR(ip + ":" + s->getPort()); } void ServerConfigDialog::updatePort() { QSettings *settings = new QSettings(YACReader::getSettingsPath() + "/YACReaderLibrary.ini", QSettings::IniFormat); // TODO unificar la creación del fichero de config con el servidor settings->beginGroup("listener"); settings->setValue("port", port->text().toInt()); settings->endGroup(); s->stop(); s->start(); generateQR(ip->currentText() + ":" + port->text()); } QrEncoder::QrEncoder() { #ifdef Q_OS_MACOS QLibrary encoder(QCoreApplication::applicationDirPath() + "/utils/libqrencode.dylib"); #else QLibrary encoder("qrencode"); #endif QRcode_encodeString8bit = (_QRcode_encodeString8bit)encoder.resolve("QRcode_encodeString8bit"); QRcode_free = (_QRcode_free)encoder.resolve("QRcode_free"); } QBitmap QrEncoder::encode(const QString &string) { if (!QRcode_encodeString8bit) { return QBitmap(); } QRcode *code; code = QRcode_encodeString8bit(string.toUtf8().data(), 0, 0); QBitmap result(code->width, code->width); result.fill(); /* convert to QBitmap */ QPainter painter; painter.begin(&result); unsigned char *pointer = code->data; for (int x = 0; x < code->width; x++) { for (int y = 0; y < code->width; y++) { if ((*pointer++ & 0x1) == 1) { painter.drawPoint(x, y); } } } painter.end(); QRcode_free(code); return result; }