1 // Copyright 2010 Ilkka Tengvall
3 // This file is part of Woller.
5 // Woller is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
10 // Woller is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with Woller. If not, see <http://www.gnu.org/licenses/>.
22 Woller::Woller(QWidget *parent)
25 QList<QString> targets;
26 status_orig = new QString(
27 tr("Choose the target or configure and fire it up!"));
28 status_timer = new QTimer(this);
29 hosts_list = new QList<host_s>;
30 settings = new QSettings("woller", "woller");
31 // build the main widget
32 this->setWindowIcon(QIcon::fromTheme("woller", QIcon(":/woller.png")));
33 status_lbl = new QLabel(*status_orig , this);
34 fire_btn = new QPushButton(tr("Wake UP"), this);
36 tr("Press the button to wake up selected target (or config)"));
37 fire_btn->setIcon(QIcon::fromTheme("woller", QIcon(":/woller.png")));
38 targets_cb = new QComboBox(this);
39 targets_cb->setToolTip(
40 tr("Choose host to wake up, or configure hosts option"));
42 vlayout = new QVBoxLayout();
43 hlayout = new QHBoxLayout();
44 hlayout->addWidget(targets_cb);
45 hlayout->addWidget(fire_btn);
46 vlayout->addWidget(status_lbl);
47 vlayout->addLayout(hlayout);
48 this->setLayout(vlayout);
49 this->setWindowTitle(tr("Woller-program"));
54 target = new wol_target;
56 connect(fire_btn, SIGNAL(clicked()), this, SLOT(send_pkt()));
57 connect(targets_cb, SIGNAL(activated(int)), this, SLOT(targets_act(int)));
62 int i = targets_cb->currentIndex();
63 qDebug() << "~Woller" << endl;
64 qDebug() << "~Woller last" << i << endl;
65 settings->setValue("last selected", i);
66 settings->setValue("position", pos());
79 void Woller::send_pkt()
81 int t = targets_cb->currentIndex();
89 if (!hosts_list->isEmpty() && t-1 <= hosts_list->count())
91 QString status = "Sent wakeup packet to ";
92 status.append(hosts_list->at(t-1).hostname);
93 target->set_mac(hosts_list->at(t-1).mac);
94 target->set_ip(hosts_list->at(t-1).ip);
96 status_lbl->setText(status);
97 status_timer->singleShot(5000, this, SLOT(reset_status()));
102 void Woller::reset_status()
104 status_lbl->setText(*status_orig);
107 void Woller::targets_act(int i)
111 // build the config widget
112 qDebug() << "building the config" << endl;
113 config_win = new ConfigWidget(0, hosts_list);
114 config_win->setWindowModality(Qt::ApplicationModal);
115 connect(config_win, SIGNAL(hosts_changed()), this, SLOT(hosts_changed()));
120 qDebug() << "targets: " << targets_cb->currentText() << endl;
124 void Woller::add_new(host_s *host)
126 qDebug() << "add_new:" << host->hostname << host->ip << host->mac << endl;
129 void Woller::do_list()
131 qDebug() << "do_list" << endl;
134 targets_cb->addItem(tr("Configure Targets"));
135 for (int i = 0; i < hosts_list->size(); ++i) {
136 targets_cb->addItem(hosts_list->at(i).hostname);
140 void Woller::hosts_changed()
142 qDebug() << "hosts_changed" << endl;
147 void Woller::save_config()
149 qDebug() << "save config" << endl;
150 settings->beginWriteArray("targets");
151 for (int i = 0; i < hosts_list->count(); ++i) {
152 settings->setArrayIndex(i);
153 settings->setValue("hostname", hosts_list->at(i).hostname);
154 settings->setValue("ip", hosts_list->at(i).ip.toString().toAscii());
155 settings->setValue("mac", hosts_list->at(i).mac.toAscii());
157 settings->endArray();
160 void Woller::load_config()
163 qDebug() << "loading config" << endl;
164 int size = settings->beginReadArray("targets");
165 for (int i = 0; i < size; ++i) {
166 settings->setArrayIndex(i);
167 host.hostname = settings->value("hostname").toString();
168 host.ip.setAddress(settings->value("ip").toString());
169 host.mac = settings->value("mac").toString();
170 hosts_list->append(host);
172 settings->endArray();
174 move(settings->value("position", QPoint(200, 200)).toPoint());
178 targets_cb->setCurrentIndex(settings->value("last selected", 0).toInt());
182 ConfigWidget::ConfigWidget(QWidget *parent, QList<host_s> *hosts)
185 qDebug() << "ConfigWidget" << endl;
188 //add buttons and the list
189 this->setWindowTitle(tr("Woller Config"));
190 add_host = new QPushButton(tr("&Add Host"), this);
191 edit_host = new QPushButton(tr("&Edit Host"), this);
192 del_host = new QPushButton(tr("&Delete Host"), this);
193 save_btn = new QPushButton(tr("&Save"), this);
194 close_btn = new QPushButton(tr("&Close"), this);
195 list = new QListWidget(this);
196 button_layout = new QVBoxLayout();
197 layout = new QHBoxLayout();
198 button_layout->addWidget(add_host);
199 button_layout->addWidget(edit_host);
200 button_layout->addWidget(del_host);
201 button_layout->addWidget(save_btn);
202 button_layout->addWidget(close_btn);
203 layout->addWidget(list);
204 layout->addLayout(button_layout);
205 this->setLayout(layout);
206 close_btn->setDefault(true);
207 edit_host->setDisabled(true);
208 del_host->setDisabled(true);
209 save_btn->setDisabled(true);
211 connect(add_host, SIGNAL(clicked()), this, SLOT(add_sig()));
212 connect(edit_host, SIGNAL(clicked()), this, SLOT(edit_sig()));
213 connect(del_host, SIGNAL(clicked()), this, SLOT(del_sig()));
214 connect(save_btn, SIGNAL(clicked()), this, SLOT(save_sig()));
215 connect(close_btn, SIGNAL(clicked()), this, SLOT(close_sig()));
216 connect(list, SIGNAL(itemClicked(QListWidgetItem *)), this,
218 connect(list, SIGNAL(itemActivated(QListWidgetItem *)), this,
221 for (int i = 0; i < hosts_list->size(); ++i) {
222 list->addItem(hosts_list->at(i).hostname);
226 ConfigWidget::~ConfigWidget()
234 delete button_layout;
239 void ConfigWidget::add_sig()
241 qDebug() << "conf add" << endl;
242 host_tmp.hostname.clear();
243 host_tmp.mac.clear();
245 host_widget = new HostWidget(0, &host_tmp);
247 host_widget->setWindowModality(Qt::ApplicationModal);
248 connect(host_widget, SIGNAL(change_host()), this, SLOT(host_added()));
250 qDebug() << "conf add - exit" << endl;
254 void ConfigWidget::edit_sig()
256 qDebug() << "conf edit" << endl;
257 host_tmp.hostname = hosts_list->at(list->currentIndex().row()).hostname;
258 host_tmp.mac = hosts_list->at(list->currentIndex().row()).mac;
259 host_tmp.ip = hosts_list->at(list->currentIndex().row()).ip;
260 host_widget = new HostWidget(0, &host_tmp);
261 connect(host_widget, SIGNAL(change_host()), this, SLOT(host_edited()));
263 host_widget->setWindowModality(Qt::ApplicationModal);
264 //hostWidget->hostname->setPlaceholderText("my_host_name");
265 //hostWidget->hostname->setText("edit1");
266 //hostWidget->mac->setPlaceholderText("001133aabbcc");
267 //hostWidget->mac->setText("001133aabbcc");
268 //hostWidget->ip->setPlaceholderText("10.10.11.255");
272 void ConfigWidget::del_sig()
275 int ret, i = list->currentIndex().row();
276 qDebug() << "conf del: " << i << endl;
278 msg_box.setText("Host is to be deleted.");
279 msg_box.setInformativeText("Do you want to save your changes?");
280 msg_box.setStandardButtons(QMessageBox::Save | QMessageBox::Cancel);
281 msg_box.setDefaultButton(QMessageBox::Save);
282 ret = msg_box.exec();
284 if ( ret == QMessageBox::Save ) {
285 hosts_list->removeAt(i);
287 emit hosts_changed();
291 void ConfigWidget::save_sig()
293 qDebug() << "conf save" << endl;
294 emit hosts_changed();
295 save_btn->setDisabled(true);
298 void ConfigWidget::close_sig()
300 qDebug() << "conf close" << endl;
304 void ConfigWidget::select_sig()
306 qDebug() << "conf sel: " << endl;
307 edit_host->setDisabled(false);
308 del_host->setDisabled(false);
311 void ConfigWidget::host_added()
313 qDebug() << "host changed" << endl;
314 list->addItem(host_tmp.hostname);
315 qDebug() << "hostsList size:" << hosts_list->size()
316 << "count:" << hosts_list->size() << endl;
317 hosts_list->append(host_tmp);
318 qDebug() << "hostsList size:" << hosts_list->size()
319 << "count:" << hosts_list->size() << endl;
320 save_btn->setDisabled(false);
321 save_btn->setDefault(true);
324 void ConfigWidget::host_edited()
326 int i = list->currentIndex().row();
327 qDebug() << "host edited: " << i << endl;
329 hosts_list->replace(i, host_tmp);
331 list->insertItem(i, hosts_list->at(i).hostname);
332 save_btn->setDisabled(false);
333 save_btn->setDefault(true);
336 HostWidget::HostWidget(QWidget *parent, host_s *host)
339 //TODO: add setValidator and use QRegExpValidator
341 qDebug() << "host widget" << endl;
343 this->setWindowTitle("Add new WOL target host");
344 vlayout = new QVBoxLayout(this);
346 host_row = new QHBoxLayout;
347 host_lbl = new QLabel(tr("Hostname:"), this);
348 hostname = new QLineEdit(host->hostname, this);
349 hostname->setToolTip(tr("Give target computer's hostname"));
350 host_row->addWidget(host_lbl);
351 host_row->addWidget(hostname);
352 vlayout->addLayout(host_row);
354 mac_row = new QHBoxLayout;
355 mac_lbl = new QLabel(tr("Mac:"), this);
356 mac = new QLineEdit(host->mac, this);
358 tr("HW address of target, e.g. 00:01:02:AA:BB:CC. "
359 "Hint, in Linux/Unix: \"ifconfig\","
360 "in Windows \"ipconfig /all\""));
361 mac->setInputMask("HH:HH:HH:HH:HH:HH;0");
362 mac_row->addWidget(mac_lbl);
363 mac_row->addWidget(mac);
364 vlayout->addLayout(mac_row);
366 ip_row = new QHBoxLayout;
367 ip_lbl = new QLabel(tr("Bcast ip:"), this);
368 ip = new QLineEdit(host->ip.toString(), this);
370 tr("Use ip broadcast address if you want to wake up target outside"
371 "of local network, or if you have several network interfaces."
372 "E.g. 192.168.1.255. You may leave this empty if unsure."));
373 ip->setMaxLength(MAX_IP_LEN);
374 ip_row->addWidget(ip_lbl);
375 ip_row->addWidget(ip);
376 vlayout->addLayout(ip_row);
378 button_row = new QHBoxLayout;
379 cancel = new QPushButton(tr("&Cancel"), this);
380 button_row->addWidget(cancel);
381 ok = new QPushButton(tr("&Ok"), this);
382 ok->setDefault(true);
383 button_row->addWidget(ok);
384 vlayout->addLayout(button_row);
386 this->setLayout(vlayout);
388 ok->setDefault(true);
390 connect(ok, SIGNAL(clicked()), this, SLOT(ok_sig()));
391 connect(cancel, SIGNAL(clicked()), this, SLOT(cancel_sig()));
395 void HostWidget::cancel_sig()
397 qDebug() << "host cancel" << endl;
401 void HostWidget::ok_sig()
403 qDebug() << "host ok" << this->hostname->text() << this->mac->text()
404 << this->ip->text() << endl;
406 new_host->hostname = this->hostname->text();
407 if (new_host->hostname.isEmpty())
410 msgBox.setText("You must set hostname!");
414 new_host->mac= this->mac->text();
415 if (new_host->mac.isEmpty())
418 msgBox.setText("You must set mac!");
422 new_host->ip = this->ip->text();
425 qDebug() << "host ok" << new_host->hostname << new_host->mac
426 << new_host->ip << endl;
431 HostWidget::~HostWidget()
433 qDebug() << "host ~widget" << endl;
451 int wol_target::get_mac( QString *gmac)
459 int wol_target::set_mac( const QString smac )
461 if (smac.size() != MAX_MAC_LEN) {
462 qDebug() << "set mac mac size:" << smac.size() << smac << endl;
466 qDebug() << "set mac mac:" << mac;
470 int wol_target::get_ip( QHostAddress *gip)
478 int wol_target::set_ip( const QHostAddress sip )
487 wol_target::wol_target()
490 ip = new QHostAddress;
491 magic_pkt = new QByteArray;
494 wol_target::~wol_target()
501 int wol_target::create_magic_pkt(const QString *mac)
503 const char magic_header[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
504 qDebug() << "create magic pkt" << endl;
505 if (mac->size() != MAX_MAC_LEN)
507 qDebug() << "create magic pkt size:" << mac->size() << endl;
510 *magic_pkt = QByteArray::fromRawData(magic_header, sizeof(magic_header));
511 for (int i=0; i < WOL_MAGIC_MAC_CNT; i++)
512 magic_pkt->append(QByteArray::fromHex(mac->toAscii()));
516 int wol_target::wake_me()
518 QUdpSocket udpSocket;
520 if (mac->isEmpty()) {
521 qDebug() << "wakeme: no mac set" << endl;
524 create_magic_pkt(mac);
525 qDebug() << "magic:" << endl;
526 qDebug() << magic_pkt->toHex() << endl ;
529 qDebug() << "sending broadcast to mac" << *mac << endl;
530 udpSocket.writeDatagram(magic_pkt->data(), magic_pkt->size(),
531 QHostAddress::Broadcast,
535 qDebug() << "sending with ip" << *ip << endl;
536 udpSocket.writeDatagram(magic_pkt->data(), magic_pkt->size(),