--- /dev/null
+// Copyright 2010 Ilkka Tengvall
+//
+// This file is part of Woller.
+//
+// Woller is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Woller is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Woller. If not, see <http://www.gnu.org/licenses/>.
+
+
+#include "woller.h"
+
+
+Woller::Woller(QWidget *parent)
+ : QWidget(parent)
+{
+ QList<QString> targets;
+ status_orig = new QString(
+ tr("Choose the target or configure and fire it up!"));
+ status_timer = new QTimer(this);
+ hosts_list = new QList<host_s>;
+ settings = new QSettings("woller", "woller");
+ // build the main widget
+ this->setWindowIcon(QIcon::fromTheme("woller", QIcon(":/woller.png")));
+ status_lbl = new QLabel(*status_orig , this);
+ fire_btn = new QPushButton(tr("Wake UP"), this);
+ fire_btn->setToolTip(
+ tr("Press the button to wake up selected target (or config)"));
+ fire_btn->setIcon(QIcon::fromTheme("woller", QIcon(":/woller.png")));
+ targets_cb = new QComboBox(this);
+ targets_cb->setToolTip(
+ tr("Choose host to wake up, or configure hosts option"));
+
+ vlayout = new QVBoxLayout();
+ hlayout = new QHBoxLayout();
+ hlayout->addWidget(targets_cb);
+ hlayout->addWidget(fire_btn);
+ vlayout->addWidget(status_lbl);
+ vlayout->addLayout(hlayout);
+ this->setLayout(vlayout);
+ this->setWindowTitle(tr("Woller-program"));
+
+ //populate CB
+ load_config();
+
+ target = new wol_target;
+
+ connect(fire_btn, SIGNAL(clicked()), this, SLOT(send_pkt()));
+ connect(targets_cb, SIGNAL(activated(int)), this, SLOT(targets_act(int)));
+}
+
+Woller::~Woller()
+{
+ int i = targets_cb->currentIndex();
+ qDebug() << "~Woller" << endl;
+ qDebug() << "~Woller last" << i << endl;
+ settings->setValue("last selected", i);
+ settings->setValue("position", pos());
+ delete settings;
+ delete hosts_list;
+ delete status_lbl;
+ delete fire_btn;
+ delete targets_cb;
+ //delete vlayout;
+ //delete hlayout;
+ delete target;
+ delete status_orig;
+ delete status_timer;
+}
+
+void Woller::send_pkt()
+{
+ int t = targets_cb->currentIndex();
+
+ if (t == 0)
+ {
+ targets_act(0);
+ }
+ else
+ {
+ if (!hosts_list->isEmpty() && t-1 <= hosts_list->count())
+ {
+ QString status = "Sent wakeup packet to ";
+ status.append(hosts_list->at(t-1).hostname);
+ target->set_mac(hosts_list->at(t-1).mac);
+ target->set_ip(hosts_list->at(t-1).ip);
+ target->wake_me();
+ status_lbl->setText(status);
+ status_timer->singleShot(5000, this, SLOT(reset_status()));
+ }
+ }
+}
+
+void Woller::reset_status()
+{
+ status_lbl->setText(*status_orig);
+}
+
+void Woller::targets_act(int i)
+{
+ if (i == 0)
+ {
+ // build the config widget
+ qDebug() << "building the config" << endl;
+ config_win = new ConfigWidget(0, hosts_list);
+ config_win->setWindowModality(Qt::ApplicationModal);
+ connect(config_win, SIGNAL(hosts_changed()), this, SLOT(hosts_changed()));
+ config_win->show();
+ }
+ else
+ {
+ qDebug() << "targets: " << targets_cb->currentText() << endl;
+ }
+}
+
+void Woller::add_new(host_s *host)
+{
+ qDebug() << "add_new:" << host->hostname << host->ip << host->mac << endl;
+}
+
+void Woller::do_list()
+{
+ qDebug() << "do_list" << endl;
+ //populate CB
+ targets_cb->clear();
+ targets_cb->addItem(tr("Configure Targets"));
+ for (int i = 0; i < hosts_list->size(); ++i) {
+ targets_cb->addItem(hosts_list->at(i).hostname);
+ }
+}
+
+void Woller::hosts_changed()
+{
+ qDebug() << "hosts_changed" << endl;
+ do_list();
+ save_config();
+}
+
+void Woller::save_config()
+{
+ qDebug() << "save config" << endl;
+ settings->beginWriteArray("targets");
+ for (int i = 0; i < hosts_list->count(); ++i) {
+ settings->setArrayIndex(i);
+ settings->setValue("hostname", hosts_list->at(i).hostname);
+ settings->setValue("ip", hosts_list->at(i).ip.toString().toAscii());
+ settings->setValue("mac", hosts_list->at(i).mac.toAscii());
+ }
+ settings->endArray();
+}
+
+void Woller::load_config()
+{
+ host_s host;
+ qDebug() << "loading config" << endl;
+ int size = settings->beginReadArray("targets");
+ for (int i = 0; i < size; ++i) {
+ settings->setArrayIndex(i);
+ host.hostname = settings->value("hostname").toString();
+ host.ip.setAddress(settings->value("ip").toString());
+ host.mac = settings->value("mac").toString();
+ hosts_list->append(host);
+ }
+ settings->endArray();
+
+ move(settings->value("position", QPoint(200, 200)).toPoint());
+
+ do_list();
+
+ targets_cb->setCurrentIndex(settings->value("last selected", 0).toInt());
+}
+
+
+ConfigWidget::ConfigWidget(QWidget *parent, QList<host_s> *hosts)
+ : QWidget(parent)
+{
+ qDebug() << "ConfigWidget" << endl;
+ hosts_list = hosts;
+
+ //add buttons and the list
+ this->setWindowTitle(tr("Woller Config"));
+ add_host = new QPushButton(tr("&Add Host"), this);
+ edit_host = new QPushButton(tr("&Edit Host"), this);
+ del_host = new QPushButton(tr("&Delete Host"), this);
+ save_btn = new QPushButton(tr("&Save"), this);
+ close_btn = new QPushButton(tr("&Close"), this);
+ list = new QListWidget(this);
+ button_layout = new QVBoxLayout();
+ layout = new QHBoxLayout();
+ button_layout->addWidget(add_host);
+ button_layout->addWidget(edit_host);
+ button_layout->addWidget(del_host);
+ button_layout->addWidget(save_btn);
+ button_layout->addWidget(close_btn);
+ layout->addWidget(list);
+ layout->addLayout(button_layout);
+ this->setLayout(layout);
+ close_btn->setDefault(true);
+ edit_host->setDisabled(true);
+ del_host->setDisabled(true);
+ save_btn->setDisabled(true);
+
+ connect(add_host, SIGNAL(clicked()), this, SLOT(add_sig()));
+ connect(edit_host, SIGNAL(clicked()), this, SLOT(edit_sig()));
+ connect(del_host, SIGNAL(clicked()), this, SLOT(del_sig()));
+ connect(save_btn, SIGNAL(clicked()), this, SLOT(save_sig()));
+ connect(close_btn, SIGNAL(clicked()), this, SLOT(close_sig()));
+ connect(list, SIGNAL(itemClicked(QListWidgetItem *)), this,
+ SLOT(select_sig()));
+ connect(list, SIGNAL(itemActivated(QListWidgetItem *)), this,
+ SLOT(edit_sig()));
+
+ for (int i = 0; i < hosts_list->size(); ++i) {
+ list->addItem(hosts_list->at(i).hostname);
+ }
+}
+
+ConfigWidget::~ConfigWidget()
+{
+ delete add_host;
+ delete edit_host;
+ delete del_host;
+ delete save_btn;
+ delete close_btn;
+ delete list;
+ delete button_layout;
+ delete layout;
+}
+
+
+void ConfigWidget::add_sig()
+{
+ qDebug() << "conf add" << endl;
+ host_tmp.hostname.clear();
+ host_tmp.mac.clear();
+ host_tmp.ip.clear();
+ host_widget = new HostWidget(0, &host_tmp);
+
+ host_widget->setWindowModality(Qt::ApplicationModal);
+ connect(host_widget, SIGNAL(change_host()), this, SLOT(host_added()));
+ host_widget->show();
+ qDebug() << "conf add - exit" << endl;
+
+}
+
+void ConfigWidget::edit_sig()
+{
+ qDebug() << "conf edit" << endl;
+ host_tmp.hostname = hosts_list->at(list->currentIndex().row()).hostname;
+ host_tmp.mac = hosts_list->at(list->currentIndex().row()).mac;
+ host_tmp.ip = hosts_list->at(list->currentIndex().row()).ip;
+ host_widget = new HostWidget(0, &host_tmp);
+ connect(host_widget, SIGNAL(change_host()), this, SLOT(host_edited()));
+
+ host_widget->setWindowModality(Qt::ApplicationModal);
+ //hostWidget->hostname->setPlaceholderText("my_host_name");
+ //hostWidget->hostname->setText("edit1");
+ //hostWidget->mac->setPlaceholderText("001133aabbcc");
+ //hostWidget->mac->setText("001133aabbcc");
+ //hostWidget->ip->setPlaceholderText("10.10.11.255");
+ host_widget->show();
+}
+
+void ConfigWidget::del_sig()
+{
+ QMessageBox msg_box;
+ int ret, i = list->currentIndex().row();
+ qDebug() << "conf del: " << i << endl;
+
+ msg_box.setText("Host is to be deleted.");
+ msg_box.setInformativeText("Do you want to save your changes?");
+ msg_box.setStandardButtons(QMessageBox::Save | QMessageBox::Cancel);
+ msg_box.setDefaultButton(QMessageBox::Save);
+ ret = msg_box.exec();
+
+ if ( ret == QMessageBox::Save ) {
+ hosts_list->removeAt(i);
+ list->takeItem(i);
+ emit hosts_changed();
+ }
+}
+
+void ConfigWidget::save_sig()
+{
+ qDebug() << "conf save" << endl;
+ emit hosts_changed();
+ save_btn->setDisabled(true);
+}
+
+void ConfigWidget::close_sig()
+{
+ qDebug() << "conf close" << endl;
+ this->close();
+}
+
+void ConfigWidget::select_sig()
+{
+ qDebug() << "conf sel: " << endl;
+ edit_host->setDisabled(false);
+ del_host->setDisabled(false);
+}
+
+void ConfigWidget::host_added()
+{
+ qDebug() << "host changed" << endl;
+ list->addItem(host_tmp.hostname);
+ qDebug() << "hostsList size:" << hosts_list->size()
+ << "count:" << hosts_list->size() << endl;
+ hosts_list->append(host_tmp);
+ qDebug() << "hostsList size:" << hosts_list->size()
+ << "count:" << hosts_list->size() << endl;
+ save_btn->setDisabled(false);
+ save_btn->setDefault(true);
+}
+
+void ConfigWidget::host_edited()
+{
+ int i = list->currentIndex().row();
+ qDebug() << "host edited: " << i << endl;
+
+ hosts_list->replace(i, host_tmp);
+ list->takeItem(i);
+ list->insertItem(i, hosts_list->at(i).hostname);
+ save_btn->setDisabled(false);
+ save_btn->setDefault(true);
+}
+
+HostWidget::HostWidget(QWidget *parent, host_s *host)
+ : QWidget(parent)
+{
+ //TODO: add setValidator and use QRegExpValidator
+
+ qDebug() << "host widget" << endl;
+ new_host = host;
+ this->setWindowTitle("Add new WOL target host");
+ vlayout = new QVBoxLayout(this);
+
+ host_row = new QHBoxLayout;
+ host_lbl = new QLabel(tr("Hostname:"), this);
+ hostname = new QLineEdit(host->hostname, this);
+ hostname->setToolTip(tr("Give target computer's hostname"));
+ host_row->addWidget(host_lbl);
+ host_row->addWidget(hostname);
+ vlayout->addLayout(host_row);
+
+ mac_row = new QHBoxLayout;
+ mac_lbl = new QLabel(tr("Mac:"), this);
+ mac = new QLineEdit(host->mac, this);
+ mac->setToolTip(
+ tr("HW address of target, e.g. 00:01:02:AA:BB:CC. "
+ "Hint, in Linux/Unix: \"ifconfig\","
+ "in Windows \"ipconfig /all\""));
+ mac->setInputMask("HH:HH:HH:HH:HH:HH;0");
+ mac_row->addWidget(mac_lbl);
+ mac_row->addWidget(mac);
+ vlayout->addLayout(mac_row);
+
+ ip_row = new QHBoxLayout;
+ ip_lbl = new QLabel(tr("Bcast ip:"), this);
+ ip = new QLineEdit(host->ip.toString(), this);
+ ip->setToolTip(
+ tr("Use ip broadcast address if you want to wake up target outside"
+ "of local network, or if you have several network interfaces."
+ "E.g. 192.168.1.255. You may leave this empty if unsure."));
+ ip->setMaxLength(MAX_IP_LEN);
+ ip_row->addWidget(ip_lbl);
+ ip_row->addWidget(ip);
+ vlayout->addLayout(ip_row);
+
+ button_row = new QHBoxLayout;
+ cancel = new QPushButton(tr("&Cancel"), this);
+ button_row->addWidget(cancel);
+ ok = new QPushButton(tr("&Ok"), this);
+ ok->setDefault(true);
+ button_row->addWidget(ok);
+ vlayout->addLayout(button_row);
+
+ this->setLayout(vlayout);
+
+ ok->setDefault(true);
+
+ connect(ok, SIGNAL(clicked()), this, SLOT(ok_sig()));
+ connect(cancel, SIGNAL(clicked()), this, SLOT(cancel_sig()));
+
+}
+
+void HostWidget::cancel_sig()
+{
+ qDebug() << "host cancel" << endl;
+ this->close();
+}
+
+void HostWidget::ok_sig()
+{
+ qDebug() << "host ok" << this->hostname->text() << this->mac->text()
+ << this->ip->text() << endl;
+
+ new_host->hostname = this->hostname->text();
+ if (new_host->hostname.isEmpty())
+ {
+ QMessageBox msgBox;
+ msgBox.setText("You must set hostname!");
+ msgBox.exec();
+ return;
+ }
+ new_host->mac= this->mac->text();
+ if (new_host->mac.isEmpty())
+ {
+ QMessageBox msgBox;
+ msgBox.setText("You must set mac!");
+ msgBox.exec();
+ return;
+ }
+ new_host->ip = this->ip->text();
+ emit change_host();
+
+ qDebug() << "host ok" << new_host->hostname << new_host->mac
+ << new_host->ip << endl;
+
+ this->close();
+}
+
+HostWidget::~HostWidget()
+{
+ qDebug() << "host ~widget" << endl;
+ delete vlayout;
+ delete host_row;
+ delete host_lbl;
+ delete hostname;
+ delete mac_row;
+ delete mac_lbl;
+ delete mac;
+ delete ip_row;
+ delete ip_lbl;
+ delete ip;
+ delete button_row;
+ delete cancel;
+ delete ok;
+ //delete new_host;
+}
+
+
+int wol_target::get_mac( QString *gmac)
+{
+ if (!gmac)
+ return -1;
+ *gmac = *mac;
+ return 0;
+}
+
+int wol_target::set_mac( const QString smac )
+{
+ if (smac.size() != MAX_MAC_LEN) {
+ qDebug() << "set mac mac size:" << smac.size() << smac << endl;
+ //return -1;
+ }
+ *mac = smac;
+ qDebug() << "set mac mac:" << mac;
+ return 0;
+}
+
+int wol_target::get_ip( QHostAddress *gip)
+{
+ if (!gip)
+ return -1;
+ *gip = *ip;
+ return 0;
+}
+
+int wol_target::set_ip( const QHostAddress sip )
+{
+ if (sip.isNull())
+ return -1;
+ *ip = sip;
+ return 0;
+}
+
+
+wol_target::wol_target()
+{
+ mac = new QString;
+ ip = new QHostAddress;
+ magic_pkt = new QByteArray;
+}
+
+wol_target::~wol_target()
+{
+ delete mac;
+ delete ip;
+ delete magic_pkt;
+}
+
+int wol_target::create_magic_pkt(const QString *mac)
+{
+ const char magic_header[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ qDebug() << "create magic pkt" << endl;
+ if (mac->size() != MAX_MAC_LEN)
+ {
+ qDebug() << "create magic pkt size:" << mac->size() << endl;
+ //return -1;
+ }
+ *magic_pkt = QByteArray::fromRawData(magic_header, sizeof(magic_header));
+ for (int i=0; i < WOL_MAGIC_MAC_CNT; i++)
+ magic_pkt->append(QByteArray::fromHex(mac->toAscii()));
+ return 0;
+}
+
+int wol_target::wake_me()
+{
+ QUdpSocket udpSocket;
+
+ if (mac->isEmpty()) {
+ qDebug() << "wakeme: no mac set" << endl;
+ return -1;
+ }
+ create_magic_pkt(mac);
+ qDebug() << "magic:" << endl;
+ qDebug() << magic_pkt->toHex() << endl ;
+
+ if (ip->isNull()) {
+ qDebug() << "sending broadcast to mac" << *mac << endl;
+ udpSocket.writeDatagram(magic_pkt->data(), magic_pkt->size(),
+ QHostAddress::Broadcast,
+ WOL_MAGIC_UDP_PORT);
+ }
+ else {
+ qDebug() << "sending with ip" << *ip << endl;
+ udpSocket.writeDatagram(magic_pkt->data(), magic_pkt->size(),
+ *ip,
+ WOL_MAGIC_UDP_PORT);
+ }
+ return 0;
+}
+