blob: d1c6898cf7ab94c301b73d227be2e7f67eb192be [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>
19 */
20
21#include "chronosharegui.h"
Alexander Afanasyev83a53002013-01-24 11:12:01 -080022#include "logging.h"
Alexander Afanasyev9ca444e2013-01-25 16:29:35 -080023#include "ccnx-wrapper.h"
24
25#include <boost/make_shared.hpp>
26
27using namespace boost;
28using namespace Ccnx;
Jared Lindblom06405c42013-01-17 20:48:39 -080029
Alexander Afanasyev83a53002013-01-24 11:12:01 -080030INIT_LOGGER ("Gui");
31
32ChronoShareGui::ChronoShareGui(QWidget *parent)
Jared Lindblomc8ffd592013-01-25 00:00:30 -080033 : QDialog(parent)
Jared Lindblom06405c42013-01-17 20:48:39 -080034{
Jared Lindblomc8ffd592013-01-25 00:00:30 -080035
36 setWindowTitle("Preferences");
37
38 labelUsername = new QLabel("Username");
39 labelSharedFolder = new QLabel("Shared Folder Name");
40 labelSharedFolderPath = new QLabel("Shared Folder Path");
41 editUsername = new QLineEdit();
42 editSharedFolder = new QLineEdit();
43 editSharedFolderPath = new QLineEdit();
44 editSharedFolderPath->setReadOnly(true);
45 QPalette pal = editSharedFolderPath->palette();
46 pal.setColor(QPalette::Active, QPalette::Base, pal.color(QPalette::Disabled, QPalette::Base));
47 editSharedFolderPath->setPalette(pal);
48 button = new QPushButton("Submit");
49 label = new QLabel();
50
51 connect(button, SIGNAL(clicked()), this, SLOT(changeSettings()));
52
53 mainLayout = new QVBoxLayout; //vertically
54 mainLayout->addWidget(labelUsername);
55 mainLayout->addWidget(editUsername);
56 mainLayout->addWidget(labelSharedFolder);
57 mainLayout->addWidget(editSharedFolder);
58 mainLayout->addWidget(labelSharedFolderPath);
59 mainLayout->addWidget(editSharedFolderPath);
60 mainLayout->addWidget(button);
61 mainLayout->addWidget(label);
62 setLayout(mainLayout);
63
Alexander Afanasyev83a53002013-01-24 11:12:01 -080064 // load settings
65 if(!loadSettings())
Jared Lindblom5d7e51e2013-01-18 00:59:34 -080066 {
Alexander Afanasyev83a53002013-01-24 11:12:01 -080067 // prompt user to choose folder
Jared Lindblomc8ffd592013-01-25 00:00:30 -080068 openMessageBox("First Time Setup", "Please enter a username, shared folder name and choose the shared folder path on your local filesystem.");
69 viewSettings();
Alexander Afanasyev83a53002013-01-24 11:12:01 -080070 openFileDialog();
Jared Lindblomc8ffd592013-01-25 00:00:30 -080071 viewSettings();
Jared Lindblom5d7e51e2013-01-18 00:59:34 -080072 }
Jared Lindblomb4032e22013-01-17 23:50:51 -080073
Alexander Afanasyev83a53002013-01-24 11:12:01 -080074 // create actions that result from clicking a menu option
75 createActions();
Jared Lindblomb4032e22013-01-17 23:50:51 -080076
Alexander Afanasyev83a53002013-01-24 11:12:01 -080077 // create tray icon
78 createTrayIcon();
Jared Lindblomb4032e22013-01-17 23:50:51 -080079
Alexander Afanasyev83a53002013-01-24 11:12:01 -080080 // set icon image
81 setIcon();
Jared Lindblom06405c42013-01-17 20:48:39 -080082
Alexander Afanasyev83a53002013-01-24 11:12:01 -080083 // show tray icon
84 m_trayIcon->show();
Alexander Afanasyev9e5a4702013-01-24 13:15:23 -080085
86 // Dispatcher(const boost::filesystem::path &path, const std::string &localUserName, const Ccnx::Name &localPrefix,
87 // const std::string &sharedFolder, const boost::filesystem::path &rootDir,
88 // Ccnx::CcnxWrapperPtr ccnx, SchedulerPtr scheduler, int poolSize = 2);
89
Alexander Afanasyev9ca444e2013-01-25 16:29:35 -080090 m_dispatcher = new Dispatcher (m_username.toStdString (), m_sharedFolderName.toStdString (),
91 m_dirPath.toStdString (), make_shared<CcnxWrapper> ());
Jared Lindblomc8ffd592013-01-25 00:00:30 -080092
93 // Alex: this **must** be here, otherwise m_dirPath will be uninitialized
Alexander Afanasyev9ca444e2013-01-25 16:29:35 -080094 m_watcher = new FsWatcher (m_dirPath,
95 bind (&Dispatcher::Did_LocalFile_AddOrModify, m_dispatcher, _1),
Alexander Afanasyev0a30a0c2013-01-29 17:25:42 -080096 bind (&Dispatcher::Did_LocalFile_Delete, m_dispatcher, _1),
97 m_dispatcher->GetFileState ());
Jared Lindblom06405c42013-01-17 20:48:39 -080098}
99
100ChronoShareGui::~ChronoShareGui()
101{
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800102 delete m_watcher; // stop filewatching ASAP
Alexander Afanasyev9ca444e2013-01-25 16:29:35 -0800103 delete m_dispatcher; // stop dispatcher ASAP, but after watcher (to prevent triggering callbacks on deleted object)
Alexander Afanasyev9e5a4702013-01-24 13:15:23 -0800104
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800105 // cleanup
106 delete m_trayIcon;
107 delete m_trayIconMenu;
108 delete m_openFolder;
109 delete m_viewSettings;
110 delete m_changeFolder;
111 delete m_quitProgram;
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800112
113 delete labelUsername;
114 delete labelSharedFolder;
115 delete editUsername;
116 delete editSharedFolder;
117 delete button;
118 delete label;
119 delete mainLayout;
Jared Lindblom5d7e51e2013-01-18 00:59:34 -0800120}
121
122void ChronoShareGui::openMessageBox(QString title, QString text)
123{
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800124 QMessageBox messageBox(this);
125 messageBox.setWindowTitle(title);
126 messageBox.setText(text);
Jared Lindblom5d7e51e2013-01-18 00:59:34 -0800127
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800128 messageBox.setIconPixmap(QPixmap(":/images/friends-group-icon.png"));
Jared Lindblom5d7e51e2013-01-18 00:59:34 -0800129
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800130 messageBox.exec();
Jared Lindblom5d7e51e2013-01-18 00:59:34 -0800131}
132
133void ChronoShareGui::openMessageBox(QString title, QString text, QString infotext)
134{
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800135 QMessageBox messageBox(this);
136 messageBox.setWindowTitle(title);
137 messageBox.setText(text);
138 messageBox.setInformativeText(infotext);
Jared Lindblom5d7e51e2013-01-18 00:59:34 -0800139
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800140 messageBox.setIconPixmap(QPixmap(":/images/friends-group-icon.png"));
Jared Lindblom5d7e51e2013-01-18 00:59:34 -0800141
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800142 messageBox.exec();
Jared Lindblom06405c42013-01-17 20:48:39 -0800143}
144
145void ChronoShareGui::createActions()
146{
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800147 // create the "open folder" action
148 m_openFolder = new QAction(tr("&Open Folder"), this);
149 connect(m_openFolder, SIGNAL(triggered()), this, SLOT(openSharedFolder()));
Jared Lindblom06405c42013-01-17 20:48:39 -0800150
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800151 // create the "view settings" action
152 m_viewSettings = new QAction(tr("&View Settings"), this);
153 connect(m_viewSettings, SIGNAL(triggered()), this, SLOT(viewSettings()));
Jared Lindblom5d7e51e2013-01-18 00:59:34 -0800154
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800155 // create the "change folder" action
156 m_changeFolder = new QAction(tr("&Change Folder"), this);
157 connect(m_changeFolder, SIGNAL(triggered()), this, SLOT(openFileDialog()));
Jared Lindblomb4032e22013-01-17 23:50:51 -0800158
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800159 // create the "quit program" action
160 m_quitProgram = new QAction(tr("&Quit"), this);
161 connect(m_quitProgram, SIGNAL(triggered()), qApp, SLOT(quit()));
Jared Lindblom06405c42013-01-17 20:48:39 -0800162}
163
164void ChronoShareGui::createTrayIcon()
165{
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800166 // create a new icon menu
167 m_trayIconMenu = new QMenu(this);
Jared Lindblom06405c42013-01-17 20:48:39 -0800168
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800169 // add actions to the menu
170 m_trayIconMenu->addAction(m_openFolder);
171 m_trayIconMenu->addSeparator();
172 m_trayIconMenu->addAction(m_viewSettings);
173 m_trayIconMenu->addAction(m_changeFolder);
174 m_trayIconMenu->addSeparator();
175 m_trayIconMenu->addAction(m_quitProgram);
Jared Lindblom06405c42013-01-17 20:48:39 -0800176
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800177 // create new tray icon
178 m_trayIcon = new QSystemTrayIcon(this);
Jared Lindblomb4032e22013-01-17 23:50:51 -0800179
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800180 // associate the menu with the tray icon
181 m_trayIcon->setContextMenu(m_trayIconMenu);
Jared Lindblomb4032e22013-01-17 23:50:51 -0800182
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800183 // handle left click of icon
184 connect(m_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayIconClicked(QSystemTrayIcon::ActivationReason)));
Jared Lindblom06405c42013-01-17 20:48:39 -0800185}
186
187void ChronoShareGui::setIcon()
188{
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800189 // set the icon image
190 m_trayIcon->setIcon(QIcon(":/images/friends-group-icon.png"));
Jared Lindblom06405c42013-01-17 20:48:39 -0800191}
192
193void ChronoShareGui::openSharedFolder()
194{
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800195 // Alex: isn't there an OS-independent way in QT for this?
Jared Lindblomb4032e22013-01-17 23:50:51 -0800196
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800197 // tell Finder to open the shared folder
198 QStringList scriptArgs;
199 scriptArgs << QLatin1String("-e")
200 << QString::fromLatin1("tell application \"Finder\" to reveal POSIX file \"%1\"")
201 .arg(m_dirPath);
Jared Lindblomb4032e22013-01-17 23:50:51 -0800202
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800203 // execute the commands to make it happen
204 QProcess::execute(QLatin1String("/usr/bin/osascript"), scriptArgs);
Jared Lindblomb4032e22013-01-17 23:50:51 -0800205
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800206 // clear command arguments
207 scriptArgs.clear();
Jared Lindblomb4032e22013-01-17 23:50:51 -0800208
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800209 // tell Finder to appear
210 scriptArgs << QLatin1String("-e")
211 << QLatin1String("tell application \"Finder\" to activate");
212
213 // execute the commands to make it happen
214 QProcess::execute("/usr/bin/osascript", scriptArgs);
Jared Lindblom06405c42013-01-17 20:48:39 -0800215}
Jared Lindblomb4032e22013-01-17 23:50:51 -0800216
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800217void ChronoShareGui::changeSettings()
218{
219 if(!editUsername->text().isEmpty())
220 m_username = editUsername->text();
221 else
222 editUsername->setText(m_username);
223
224 if(!editSharedFolder->text().isEmpty())
225 m_sharedFolderName = editSharedFolder->text();
226 else
227 editSharedFolder->setText(m_sharedFolderName);
228
229 saveSettings();
230 this->hide();
231}
232
Jared Lindblomb4032e22013-01-17 23:50:51 -0800233void ChronoShareGui::openFileDialog()
234{
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800235 // prompt user for new directory
236 QString tempPath = QFileDialog::getExistingDirectory(this, tr("Choose a new folder"),
Alexander Afanasyev9e5a4702013-01-24 13:15:23 -0800237 m_dirPath, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
238 QFileInfo qFileInfo (tempPath);
Jared Lindblom5d7e51e2013-01-18 00:59:34 -0800239
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800240 if(qFileInfo.isDir())
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800241 {
242 m_dirPath = tempPath;
243 editSharedFolderPath->setText(m_dirPath);
244 }
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800245 else
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800246 {
247 openMessageBox ("Error", "Not a valid folder, Ignoring.");
248 }
Jared Lindblomb4032e22013-01-17 23:50:51 -0800249
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800250 _LOG_DEBUG ("Selected path: " << m_dirPath.toStdString ());
Jared Lindblomb4032e22013-01-17 23:50:51 -0800251
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800252 // save settings
253 saveSettings();
Jared Lindblomb4032e22013-01-17 23:50:51 -0800254}
255
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800256void ChronoShareGui::trayIconClicked (QSystemTrayIcon::ActivationReason reason)
Jared Lindblomb4032e22013-01-17 23:50:51 -0800257{
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800258 // if double clicked, open shared folder
259 if(reason == QSystemTrayIcon::DoubleClick)
Jared Lindblomb4032e22013-01-17 23:50:51 -0800260 {
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800261 openSharedFolder();
Jared Lindblomb4032e22013-01-17 23:50:51 -0800262 }
263}
264
Jared Lindblom5d7e51e2013-01-18 00:59:34 -0800265void ChronoShareGui::viewSettings()
Jared Lindblomb4032e22013-01-17 23:50:51 -0800266{
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800267 //simple for now
268 this->show();
Jared Lindblom5d7e51e2013-01-18 00:59:34 -0800269}
270
271bool ChronoShareGui::loadSettings()
272{
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800273 bool successful = true;
Jared Lindblom5d7e51e2013-01-18 00:59:34 -0800274
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800275 // Load Settings
276 // QSettings settings(m_settingsFilePath, QSettings::NativeFormat);
277 QSettings settings (QSettings::NativeFormat, QSettings::UserScope, "irl.cs.ucla.edu", "ChronoShare");
Jared Lindblom5d7e51e2013-01-18 00:59:34 -0800278
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800279 // _LOG_DEBUG (lexical_cast<string> (settings.allKeys()));
280
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800281 if(settings.contains("username"))
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800282 {
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800283 m_username = settings.value("username", "admin").toString();
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800284 }
285 else
286 {
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800287 successful = false;
288 }
289
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800290 editUsername->setText(m_username);
291
292 if(settings.contains("sharedfoldername"))
293 {
294 m_sharedFolderName = settings.value("sharedfoldername", "shared").toString();
295 }
296 else
297 {
298 successful = false;
299 }
300
301 editSharedFolder->setText(m_sharedFolderName);
302
303 if(settings.contains("dirPath"))
304 {
305 m_dirPath = settings.value("dirPath", QDir::homePath()).toString();
306 }
307 else
308 {
309 successful = false;
310 }
311
312 editSharedFolderPath->setText(m_dirPath);
313
314 _LOG_DEBUG ("Found configured path: " << (successful ? m_dirPath.toStdString () : std::string("no")));
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800315
316 return successful;
Jared Lindblomb4032e22013-01-17 23:50:51 -0800317}
318
319void ChronoShareGui::saveSettings()
320{
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800321 // Save Settings
322 // QSettings settings(m_settingsFilePath, QSettings::NativeFormat);
323 QSettings settings (QSettings::NativeFormat, QSettings::UserScope, "irl.cs.ucla.edu", "ChronoShare");
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800324
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800325 settings.setValue("dirPath", m_dirPath);
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800326 settings.setValue("username", m_username);
327 settings.setValue("sharedfoldername", m_sharedFolderName);
Jared Lindblomb4032e22013-01-17 23:50:51 -0800328}
329
330void ChronoShareGui::closeEvent(QCloseEvent* event)
331{
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800332 _LOG_DEBUG ("Close Event")
Jared Lindblomc8ffd592013-01-25 00:00:30 -0800333 this->hide();
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800334 event->ignore(); // don't let the event propagate to the base class
Jared Lindblomb4032e22013-01-17 23:50:51 -0800335}
Jared Lindblomdc845f02013-01-18 17:29:40 -0800336
337#if WAF
338#include "chronosharegui.moc"
339#include "chronosharegui.cpp.moc"
Alexander Afanasyev83a53002013-01-24 11:12:01 -0800340#endif