blob: bc02c702732ebd42dc9ddcd21106cadcabcd5c0f [file] [log] [blame]
Jared Lindblom06405c42013-01-17 20:48:39 -08001/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2012-2013 University of California, Los Angeles
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Jared Lindblom <lindblom@cs.ucla.edu>
Alexander Afanasyev85a4ba02013-02-24 16:30:17 -080019 * Alexander Afanasyev <alexander.afanasyev@ucla.edu>
20 * Zhenkai Zhu <zhenkai@cs.ucla.edu>
21 * Ilya Moiseenko <iliamo@ucla.edu>
Jared Lindblom06405c42013-01-17 20:48:39 -080022 */
23
24#include "chronosharegui.h"
Alexander Afanasyev85a4ba02013-02-24 16:30:17 -080025
Alexander Afanasyev83a53002013-01-24 11:12:01 -080026#include "logging.h"
Alexander Afanasyev9ca444e2013-01-25 16:29:35 -080027#include "ccnx-wrapper.h"
Zhenkai Zhuf3ea97a2013-01-30 15:20:52 -080028#include <QValidator>
Zhenkai Zhuce04cb42013-02-25 15:29:31 -080029#include <QDir>
Zhenkai Zhu25e13582013-02-27 15:33:01 -080030#include <QFileInfo>
Zhenkai Zhuce04cb42013-02-25 15:29:31 -080031#include <QDesktopServices>
Alexander Afanasyev9ca444e2013-01-25 16:29:35 -080032
33#include <boost/make_shared.hpp>
34
35using namespace boost;
36using namespace Ccnx;
Jared Lindblom06405c42013-01-17 20:48:39 -080037
Zhenkai Zhud9429222013-02-25 22:34:09 -080038static const string HTTP_SERVER_ADDRESS = "localhost";
39static const string HTTP_SERVER_PORT = "9001";
Zhenkai Zhu5c2475b2013-02-26 22:57:31 -080040//static const string DOC_ROOT = ":/html";
41static const string DOC_ROOT = "gui/html";
Zhenkai Zhud9429222013-02-25 22:34:09 -080042static const QString ICON_PICTURE_QSTRING(":/images/friends-group-icon.png");
43
Alexander Afanasyev83a53002013-01-24 11:12:01 -080044INIT_LOGGER ("Gui");
45
46ChronoShareGui::ChronoShareGui(QWidget *parent)
Jared Lindblomc8ffd592013-01-25 00:00:30 -080047 : QDialog(parent)
Zhenkai Zhud5756312013-01-31 13:49:45 -080048 , m_watcher(0)
49 , m_dispatcher(0)
Zhenkai Zhud9429222013-02-25 22:34:09 -080050 , m_httpServer(0)
Alexander Afanasyev85a4ba02013-02-24 16:30:17 -080051#ifdef ADHOC_SUPPORTED
52 , m_executor (1)
53#endif
Zhenkai Zhuaca6cb52013-02-24 23:34:03 -080054#ifdef SPARKLE_SUPPORTED
Zhenkai Zhu8e3e9072013-02-28 15:40:51 -080055 , m_autoUpdate(new SparkleAutoUpdate(tr("http://irl.cs.ucla.edu/~zhenkai/chronoshare_dist/chronoshare.xml")))
Zhenkai Zhuaca6cb52013-02-24 23:34:03 -080056#endif
Jared Lindblom06405c42013-01-17 20:48:39 -080057{
Jared Lindblomf4b900e2013-02-07 18:08:47 -080058 setWindowTitle("Settings");
Jared Lindblomc8ffd592013-01-25 00:00:30 -080059
Jared Lindblomd8b76ad2013-02-07 20:37:37 -080060 labelUsername = new QLabel("Username (hint: /<username>)");
Jared Lindblomc8ffd592013-01-25 00:00:30 -080061 labelSharedFolder = new QLabel("Shared Folder Name");
62 labelSharedFolderPath = new QLabel("Shared Folder Path");
Zhenkai Zhuf3ea97a2013-01-30 15:20:52 -080063
Zhenkai Zhud5756312013-01-31 13:49:45 -080064 QRegExp regex("(/[^/]+)+$");
Zhenkai Zhuf3ea97a2013-01-30 15:20:52 -080065 QValidator *prefixValidator = new QRegExpValidator(regex, this);
66
Jared Lindblomc8ffd592013-01-25 00:00:30 -080067 editUsername = new QLineEdit();
Zhenkai Zhuf3ea97a2013-01-30 15:20:52 -080068 editUsername->setValidator(prefixValidator);
69
70 QRegExp noPureWhiteSpace("^\\S+.*$");
71 QValidator *wsValidator = new QRegExpValidator(noPureWhiteSpace, this);
Jared Lindblomc8ffd592013-01-25 00:00:30 -080072 editSharedFolder = new QLineEdit();
Zhenkai Zhuf3ea97a2013-01-30 15:20:52 -080073 editSharedFolder->setValidator(wsValidator);
74
Jared Lindblomc8ffd592013-01-25 00:00:30 -080075 editSharedFolderPath = new QLineEdit();
76 editSharedFolderPath->setReadOnly(true);
77 QPalette pal = editSharedFolderPath->palette();
78 pal.setColor(QPalette::Active, QPalette::Base, pal.color(QPalette::Disabled, QPalette::Base));
79 editSharedFolderPath->setPalette(pal);
80 button = new QPushButton("Submit");
81 label = new QLabel();
82
83 connect(button, SIGNAL(clicked()), this, SLOT(changeSettings()));
84
85 mainLayout = new QVBoxLayout; //vertically
86 mainLayout->addWidget(labelUsername);
87 mainLayout->addWidget(editUsername);
88 mainLayout->addWidget(labelSharedFolder);
89 mainLayout->addWidget(editSharedFolder);
90 mainLayout->addWidget(labelSharedFolderPath);
91 mainLayout->addWidget(editSharedFolderPath);
92 mainLayout->addWidget(button);
93 mainLayout->addWidget(label);
94 setLayout(mainLayout);
95
Alexander Afanasyev83a53002013-01-24 11:12:01 -080096 // create actions that result from clicking a menu option
Zhenkai Zhu25e13582013-02-27 15:33:01 -080097 createActionsAndMenu();
Jared Lindblomb4032e22013-01-17 23:50:51 -080098
Alexander Afanasyev83a53002013-01-24 11:12:01 -080099 // create tray icon
100 createTrayIcon();
Jared Lindblomb4032e22013-01-17 23:50:51 -0800101
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800102 // set icon image
103 setIcon();
Jared Lindblom06405c42013-01-17 20:48:39 -0800104
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800105 // show tray icon
106 m_trayIcon->show();
Alexander Afanasyev9e5a4702013-01-24 13:15:23 -0800107
108 // Dispatcher(const boost::filesystem::path &path, const std::string &localUserName, const Ccnx::Name &localPrefix,
109 // const std::string &sharedFolder, const boost::filesystem::path &rootDir,
110 // Ccnx::CcnxWrapperPtr ccnx, SchedulerPtr scheduler, int poolSize = 2);
111
Zhenkai Zhud5756312013-01-31 13:49:45 -0800112 // load settings
113 if(!loadSettings())
114 {
115 // prompt user to choose folder
116 openMessageBox("First Time Setup", "Please enter a username, shared folder name and choose the shared folder path on your local filesystem.");
117 viewSettings();
118 openFileDialog();
119 viewSettings();
120 }
121 else
122 {
123 startBackend();
124 }
Alexander Afanasyev85a4ba02013-02-24 16:30:17 -0800125
126#ifdef ADHOC_SUPPORTED
127 m_executor.start ();
128#endif
Zhenkai Zhud5756312013-01-31 13:49:45 -0800129}
130
131void
132ChronoShareGui::startBackend()
133{
134 if (m_watcher != 0 && m_dispatcher != 0)
135 {
136 return;
137 }
138
Alexander Afanasyev9ca444e2013-01-25 16:29:35 -0800139 m_dispatcher = new Dispatcher (m_username.toStdString (), m_sharedFolderName.toStdString (),
140 m_dirPath.toStdString (), make_shared<CcnxWrapper> ());
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800141
142 // Alex: this **must** be here, otherwise m_dirPath will be uninitialized
Alexander Afanasyev9ca444e2013-01-25 16:29:35 -0800143 m_watcher = new FsWatcher (m_dirPath,
144 bind (&Dispatcher::Did_LocalFile_AddOrModify, m_dispatcher, _1),
Zhenkai Zhud1756272013-02-01 17:02:18 -0800145 bind (&Dispatcher::Did_LocalFile_Delete, m_dispatcher, _1));
Zhenkai Zhud9429222013-02-25 22:34:09 -0800146 QFileInfo indexHtmlInfo(":/html/index.html");
147 if (indexHtmlInfo.exists())
148 {
149 m_httpServer = new http::server::server(HTTP_SERVER_ADDRESS, HTTP_SERVER_PORT, DOC_ROOT);
150 m_httpServerThread = boost::thread(&http::server::server::run, m_httpServer);
151 }
152 else
153 {
154 _LOG_ERROR ("Http server doc root dir does not exist!");
155 // shall we bail here?
156 }
Jared Lindblom06405c42013-01-17 20:48:39 -0800157}
158
159ChronoShareGui::~ChronoShareGui()
160{
Alexander Afanasyev85a4ba02013-02-24 16:30:17 -0800161#ifdef ADHOC_SUPPORTED
162 m_executor.shutdown ();
163#endif
164
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800165 delete m_watcher; // stop filewatching ASAP
Alexander Afanasyev9ca444e2013-01-25 16:29:35 -0800166 delete m_dispatcher; // stop dispatcher ASAP, but after watcher (to prevent triggering callbacks on deleted object)
Zhenkai Zhu377cbeb2013-02-28 16:36:26 -0800167 m_httpServer->handle_stop();
168 m_httpServerThread.join();
Zhenkai Zhud9429222013-02-25 22:34:09 -0800169 delete m_httpServer;
Alexander Afanasyev9e5a4702013-01-24 13:15:23 -0800170
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800171 // cleanup
172 delete m_trayIcon;
173 delete m_trayIconMenu;
Alexander Afanasyev85a4ba02013-02-24 16:30:17 -0800174#ifdef ADHOC_SUPPORTED
175 delete m_wifiAction;
176#endif
Zhenkai Zhuaca6cb52013-02-24 23:34:03 -0800177#ifdef SPARKLE_SUPPORTED
178 delete m_autoUpdate;
Zhenkai Zhubb170d42013-02-25 13:48:59 -0800179 delete m_checkForUpdates;
Zhenkai Zhuaca6cb52013-02-24 23:34:03 -0800180#endif
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800181 delete m_openFolder;
182 delete m_viewSettings;
183 delete m_changeFolder;
184 delete m_quitProgram;
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800185
186 delete labelUsername;
187 delete labelSharedFolder;
188 delete editUsername;
189 delete editSharedFolder;
190 delete button;
191 delete label;
192 delete mainLayout;
Jared Lindblom5d7e51e2013-01-18 00:59:34 -0800193}
194
195void ChronoShareGui::openMessageBox(QString title, QString text)
196{
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800197 QMessageBox messageBox(this);
198 messageBox.setWindowTitle(title);
199 messageBox.setText(text);
Jared Lindblom5d7e51e2013-01-18 00:59:34 -0800200
Zhenkai Zhud9429222013-02-25 22:34:09 -0800201 messageBox.setIconPixmap(QPixmap(ICON_PICTURE_QSTRING));
Jared Lindblom5d7e51e2013-01-18 00:59:34 -0800202
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800203 messageBox.exec();
Jared Lindblom5d7e51e2013-01-18 00:59:34 -0800204}
205
206void ChronoShareGui::openMessageBox(QString title, QString text, QString infotext)
207{
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800208 QMessageBox messageBox(this);
209 messageBox.setWindowTitle(title);
210 messageBox.setText(text);
211 messageBox.setInformativeText(infotext);
Jared Lindblom5d7e51e2013-01-18 00:59:34 -0800212
Zhenkai Zhud9429222013-02-25 22:34:09 -0800213 messageBox.setIconPixmap(QPixmap(ICON_PICTURE_QSTRING));
Jared Lindblom5d7e51e2013-01-18 00:59:34 -0800214
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800215 messageBox.exec();
Jared Lindblom06405c42013-01-17 20:48:39 -0800216}
217
Zhenkai Zhu25e13582013-02-27 15:33:01 -0800218void ChronoShareGui::createActionsAndMenu()
Jared Lindblom06405c42013-01-17 20:48:39 -0800219{
Alexander Afanasyev85a4ba02013-02-24 16:30:17 -0800220 _LOG_DEBUG ("Create actions");
221
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800222 // create the "open folder" action
223 m_openFolder = new QAction(tr("&Open Folder"), this);
224 connect(m_openFolder, SIGNAL(triggered()), this, SLOT(openSharedFolder()));
Jared Lindblom06405c42013-01-17 20:48:39 -0800225
Zhenkai Zhu25e13582013-02-27 15:33:01 -0800226 m_openWeb = new QAction(tr("Open in &Browser"), this);
227 connect(m_openWeb, SIGNAL(triggered()), this, SLOT(openInWebBrowser()));
228
229 m_recentFilesMenu = new QMenu(tr("Recently Changed Files"), this);
230 for (int i = 0; i < 5; i++)
231 {
232 m_fileActions[i] = new QAction(this);
233 m_fileActions[i]->setVisible(false);
234 connect(m_fileActions[i], SIGNAL(triggered()), this, SLOT(openFile()));
235 m_recentFilesMenu->addAction(m_fileActions[i]);
236 }
237 connect(m_recentFilesMenu, SIGNAL(aboutToShow()), this, SLOT(updateRecentFilesMenu()));
238
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800239 // create the "view settings" action
240 m_viewSettings = new QAction(tr("&View Settings"), this);
241 connect(m_viewSettings, SIGNAL(triggered()), this, SLOT(viewSettings()));
Jared Lindblom5d7e51e2013-01-18 00:59:34 -0800242
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800243 // create the "change folder" action
244 m_changeFolder = new QAction(tr("&Change Folder"), this);
245 connect(m_changeFolder, SIGNAL(triggered()), this, SLOT(openFileDialog()));
Jared Lindblomb4032e22013-01-17 23:50:51 -0800246
Alexander Afanasyev85a4ba02013-02-24 16:30:17 -0800247#ifdef ADHOC_SUPPORTED
248 // create "AdHoc Wifi" action
249 m_wifiAction = new QAction (tr("Enable AdHoc &WiFI"), m_trayIconMenu);
250 m_wifiAction->setChecked (false);
251 m_wifiAction->setCheckable (true);
252 connect (m_wifiAction, SIGNAL (toggled(bool)), this, SLOT(onAdHocChange(bool)));
253#endif
254
Zhenkai Zhuaca6cb52013-02-24 23:34:03 -0800255#ifdef SPARKLE_SUPPORTED
Zhenkai Zhubb170d42013-02-25 13:48:59 -0800256 m_checkForUpdates = new QAction (tr("Check For Updates"), this);
257 connect (m_checkForUpdates, SIGNAL(triggered()), this, SLOT(onCheckForUpdates()));
Zhenkai Zhuaca6cb52013-02-24 23:34:03 -0800258#endif
259
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800260 // create the "quit program" action
261 m_quitProgram = new QAction(tr("&Quit"), this);
262 connect(m_quitProgram, SIGNAL(triggered()), qApp, SLOT(quit()));
Jared Lindblom06405c42013-01-17 20:48:39 -0800263}
264
265void ChronoShareGui::createTrayIcon()
266{
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800267 // create a new icon menu
268 m_trayIconMenu = new QMenu(this);
Jared Lindblom06405c42013-01-17 20:48:39 -0800269
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800270 // add actions to the menu
271 m_trayIconMenu->addAction(m_openFolder);
Zhenkai Zhu25e13582013-02-27 15:33:01 -0800272 m_trayIconMenu->addAction(m_openWeb);
273 m_trayIconMenu->addMenu(m_recentFilesMenu);
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800274 m_trayIconMenu->addSeparator();
275 m_trayIconMenu->addAction(m_viewSettings);
276 m_trayIconMenu->addAction(m_changeFolder);
277 m_trayIconMenu->addSeparator();
Zhenkai Zhu3857d712013-02-27 22:51:25 -0800278 m_trayIconMenu->addAction(m_checkForUpdates);
279 m_trayIconMenu->addSeparator();
Alexander Afanasyev85a4ba02013-02-24 16:30:17 -0800280 m_trayIconMenu->addAction(m_wifiAction);
281 m_trayIconMenu->addSeparator();
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800282 m_trayIconMenu->addAction(m_quitProgram);
Jared Lindblom06405c42013-01-17 20:48:39 -0800283
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800284 // create new tray icon
285 m_trayIcon = new QSystemTrayIcon(this);
Jared Lindblomb4032e22013-01-17 23:50:51 -0800286
Alexander Afanasyev85a4ba02013-02-24 16:30:17 -0800287#ifdef ADHOC_SUPPORTED
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800288 // associate the menu with the tray icon
289 m_trayIcon->setContextMenu(m_trayIconMenu);
Alexander Afanasyev85a4ba02013-02-24 16:30:17 -0800290#endif
Jared Lindblomb4032e22013-01-17 23:50:51 -0800291
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800292 // handle left click of icon
293 connect(m_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayIconClicked(QSystemTrayIcon::ActivationReason)));
Jared Lindblom06405c42013-01-17 20:48:39 -0800294}
295
Alexander Afanasyev85a4ba02013-02-24 16:30:17 -0800296void
297ChronoShareGui::onAdHocChange (bool state)
298{
299#ifdef ADHOC_SUPPORTED
300 if (m_wifiAction->isChecked ())
301 {
302 QMessageBox msgBox;
303 msgBox.setText ("WARNING: your WiFi will be disconnected");
304 msgBox.setIcon (QMessageBox::Warning);
305 msgBox.setInformativeText("AdHoc WiFi will disconnect your current WiFi.\n Are you sure that you are OK with that?");
306 msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
307 msgBox.setDefaultButton(QMessageBox::Cancel);
308 int ret = msgBox.exec();
309
310 if (ret == QMessageBox::Cancel)
311 {
312 m_wifiAction->setChecked (false);
313 }
314 else
315 {
316
317 m_wifiAction->setText (tr("Disable AdHoc WiFI"));
318
319 // create adhoc
320 m_executor.execute (Adhoc::CreateAdhoc);
321 }
322 }
323 else
324 {
325 m_wifiAction->setText (tr("Enable AdHoc WiFI"));
326
327 // disable adhoc
328 m_executor.execute (Adhoc::DestroyAdhoc);
329
330 // a trick in DestroyAdhoc ensures that WiFi will be reconnected to a default WiFi
331 }
332#endif
333}
334
Zhenkai Zhuaca6cb52013-02-24 23:34:03 -0800335void
336ChronoShareGui::onCheckForUpdates()
337{
Zhenkai Zhu249fbc72013-02-27 21:50:25 -0800338#ifdef SPARKLE_SUPPORTED
Zhenkai Zhu3857d712013-02-27 22:51:25 -0800339 cout << "+++++++++++ trying to update +++++++ " << endl;
Zhenkai Zhuaca6cb52013-02-24 23:34:03 -0800340 m_autoUpdate->checkForUpdates();
Zhenkai Zhu3857d712013-02-27 22:51:25 -0800341 cout << "+++++++++++ end trying to update +++++++ " << endl;
Zhenkai Zhuaca6cb52013-02-24 23:34:03 -0800342#endif
Zhenkai Zhu249fbc72013-02-27 21:50:25 -0800343}
Zhenkai Zhuaca6cb52013-02-24 23:34:03 -0800344
Jared Lindblom06405c42013-01-17 20:48:39 -0800345void ChronoShareGui::setIcon()
346{
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800347 // set the icon image
Zhenkai Zhud9429222013-02-25 22:34:09 -0800348 m_trayIcon->setIcon(QIcon(ICON_PICTURE_QSTRING));
Jared Lindblom06405c42013-01-17 20:48:39 -0800349}
350
351void ChronoShareGui::openSharedFolder()
352{
Zhenkai Zhuce04cb42013-02-25 15:29:31 -0800353 QString path = QDir::toNativeSeparators(m_dirPath);
354 QDesktopServices::openUrl(QUrl("file:///" + path));
Jared Lindblom06405c42013-01-17 20:48:39 -0800355}
Jared Lindblomb4032e22013-01-17 23:50:51 -0800356
Zhenkai Zhu25e13582013-02-27 15:33:01 -0800357void ChronoShareGui::openInWebBrowser()
358{
Alexander Afanasyevf63a5142013-02-28 02:21:42 -0800359 QUrl url ("http://localhost:9001/");
360 url.setFragment ("fileList&"
361 "user=" + QUrl::toPercentEncoding (m_username) + "&"
362 "folder=" + QUrl::toPercentEncoding (m_sharedFolderName));
363
364 // i give up. there is double encoding and I have no idea how to fight it...
365 QDesktopServices::openUrl (url);
Zhenkai Zhu25e13582013-02-27 15:33:01 -0800366}
367
368void ChronoShareGui::openFile()
369{
370 // figure out who sent the signal
371 QAction *pAction = qobject_cast<QAction*>(sender());
372 if (pAction->isEnabled())
373 {
374 // we stored full path of the file in this toolTip field
375#ifdef Q_WS_MAC
376 // we do some hack so we could show the file in Finder highlighted
377 QStringList args;
378 args << "-e";
379 args << "tell application \"Finder\"";
380 args << "-e";
381 args << "activate";
382 args << "-e";
383 args << "select POSIX file \"" + pAction->toolTip() + "/" + pAction->text() + "\"";
384 args << "-e";
385 args << "end tell";
386 QProcess::startDetached("osascript", args);
387#else
388 // too bad qt couldn't do highlighting for Linux (or Mac)
389 QDesktopServices::openUrl(QUrl("file:///" + pAction->toolTip()));
390#endif
391 }
392}
393
394void ChronoShareGui::updateRecentFilesMenu()
395{
396 for (int i = 0; i < 5; i++)
397 {
398 m_fileActions[i]->setVisible(false);
399 }
400 m_dispatcher->LookupRecentFileActions(boost::bind(&ChronoShareGui::checkFileAction, this, _1, _2, _3), 5);
401}
402
403void ChronoShareGui::checkFileAction (const std::string &filename, int action, int index)
404{
405 QString fullPath = m_dirPath + "/" + filename.c_str();
406 QFileInfo fileInfo(fullPath);
407 if (fileInfo.exists())
408 {
409 // This is a hack, we just use some field to store the path
410 m_fileActions[index]->setToolTip(fileInfo.absolutePath());
411 m_fileActions[index]->setEnabled(true);
412 }
413 else
414 {
415 // after half an hour frustrating test and search around,
416 // I think it's the problem of Qt.
417 // According to the Qt doc, the action cannot be clicked
418 // and the area would be grey, but it didn't happen
419 // User can still trigger the action, and not greyed
420 // added check in SLOT to see if the action is "enalbed"
421 // as a remedy
422 // Give up at least for now
423 m_fileActions[index]->setEnabled(false);
424 // UPDATE, file not fetched yet
425 if (action == 0)
426 {
427 QFont font;
428 // supposed by change the font, didn't happen
429 font.setWeight(QFont::Light);
430 m_fileActions[index]->setFont(font);
431 m_fileActions[index]->setToolTip(tr("Fetching..."));
432 }
433 // DELETE
434 else
435 {
436 QFont font;
437 // supposed by change the font, didn't happen
438 font.setStrikeOut(true);
439 m_fileActions[index]->setFont(font);
440 m_fileActions[index]->setToolTip(tr("Deleted..."));
441 }
442 }
443 m_fileActions[index]->setText(fileInfo.fileName());
444 m_fileActions[index]->setVisible(true);
445}
446
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800447void ChronoShareGui::changeSettings()
448{
449 if(!editUsername->text().isEmpty())
Zhenkai Zhuf3ea97a2013-01-30 15:20:52 -0800450 m_username = editUsername->text().trimmed();
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800451 else
452 editUsername->setText(m_username);
453
454 if(!editSharedFolder->text().isEmpty())
Zhenkai Zhuf3ea97a2013-01-30 15:20:52 -0800455 m_sharedFolderName = editSharedFolder->text().trimmed();
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800456 else
457 editSharedFolder->setText(m_sharedFolderName);
458
459 saveSettings();
460 this->hide();
Zhenkai Zhud5756312013-01-31 13:49:45 -0800461
462 startBackend();
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800463}
464
Jared Lindblomb4032e22013-01-17 23:50:51 -0800465void ChronoShareGui::openFileDialog()
466{
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800467 // prompt user for new directory
468 QString tempPath = QFileDialog::getExistingDirectory(this, tr("Choose a new folder"),
Alexander Afanasyev9e5a4702013-01-24 13:15:23 -0800469 m_dirPath, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
470 QFileInfo qFileInfo (tempPath);
Jared Lindblom5d7e51e2013-01-18 00:59:34 -0800471
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800472 if(qFileInfo.isDir())
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800473 {
474 m_dirPath = tempPath;
475 editSharedFolderPath->setText(m_dirPath);
476 }
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800477 else
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800478 {
479 openMessageBox ("Error", "Not a valid folder, Ignoring.");
480 }
Jared Lindblomb4032e22013-01-17 23:50:51 -0800481
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800482 _LOG_DEBUG ("Selected path: " << m_dirPath.toStdString ());
Jared Lindblomb4032e22013-01-17 23:50:51 -0800483
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800484 // save settings
485 saveSettings();
Jared Lindblomb4032e22013-01-17 23:50:51 -0800486}
487
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800488void ChronoShareGui::trayIconClicked (QSystemTrayIcon::ActivationReason reason)
Jared Lindblomb4032e22013-01-17 23:50:51 -0800489{
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800490 // if double clicked, open shared folder
491 if(reason == QSystemTrayIcon::DoubleClick)
Jared Lindblomb4032e22013-01-17 23:50:51 -0800492 {
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800493 openSharedFolder();
Jared Lindblomb4032e22013-01-17 23:50:51 -0800494 }
495}
496
Jared Lindblom5d7e51e2013-01-18 00:59:34 -0800497void ChronoShareGui::viewSettings()
Jared Lindblomb4032e22013-01-17 23:50:51 -0800498{
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800499 //simple for now
500 this->show();
Zhenkai Zhud5756312013-01-31 13:49:45 -0800501 this->raise();
502 this->activateWindow();
Jared Lindblom5d7e51e2013-01-18 00:59:34 -0800503}
504
505bool ChronoShareGui::loadSettings()
506{
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800507 bool successful = true;
Jared Lindblom5d7e51e2013-01-18 00:59:34 -0800508
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800509 // Load Settings
510 // QSettings settings(m_settingsFilePath, QSettings::NativeFormat);
511 QSettings settings (QSettings::NativeFormat, QSettings::UserScope, "irl.cs.ucla.edu", "ChronoShare");
Jared Lindblom5d7e51e2013-01-18 00:59:34 -0800512
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800513 // _LOG_DEBUG (lexical_cast<string> (settings.allKeys()));
514
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800515 if(settings.contains("username"))
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800516 {
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800517 m_username = settings.value("username", "admin").toString();
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800518 }
519 else
520 {
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800521 successful = false;
522 }
523
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800524 editUsername->setText(m_username);
525
526 if(settings.contains("sharedfoldername"))
527 {
528 m_sharedFolderName = settings.value("sharedfoldername", "shared").toString();
529 }
530 else
531 {
532 successful = false;
533 }
534
535 editSharedFolder->setText(m_sharedFolderName);
536
537 if(settings.contains("dirPath"))
538 {
539 m_dirPath = settings.value("dirPath", QDir::homePath()).toString();
540 }
541 else
542 {
543 successful = false;
544 }
545
546 editSharedFolderPath->setText(m_dirPath);
547
548 _LOG_DEBUG ("Found configured path: " << (successful ? m_dirPath.toStdString () : std::string("no")));
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800549
550 return successful;
Jared Lindblomb4032e22013-01-17 23:50:51 -0800551}
552
553void ChronoShareGui::saveSettings()
554{
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800555 // Save Settings
556 // QSettings settings(m_settingsFilePath, QSettings::NativeFormat);
557 QSettings settings (QSettings::NativeFormat, QSettings::UserScope, "irl.cs.ucla.edu", "ChronoShare");
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800558
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800559 settings.setValue("dirPath", m_dirPath);
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800560 settings.setValue("username", m_username);
561 settings.setValue("sharedfoldername", m_sharedFolderName);
Jared Lindblomb4032e22013-01-17 23:50:51 -0800562}
563
564void ChronoShareGui::closeEvent(QCloseEvent* event)
565{
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800566 _LOG_DEBUG ("Close Event")
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800567 this->hide();
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800568 event->ignore(); // don't let the event propagate to the base class
Jared Lindblomb4032e22013-01-17 23:50:51 -0800569}
Jared Lindblomdc845f02013-01-18 17:29:40 -0800570
571#if WAF
572#include "chronosharegui.moc"
573#include "chronosharegui.cpp.moc"
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800574#endif