/**************************************************************** * RetroShare is distributed under the following license: * * Copyright (C) 2006, 2007 crypton * * This program 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 2 * of the License, or (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. ****************************************************************/ #include #include #include #include #include #include #include #include #include #include #include "ShareManager.h" #include "settings/rsharesettings.h" #include "gui/common/GroupFlagsWidget.h" #include "gui/common/GroupSelectionBox.h" #include "gui/common/GroupDefs.h" #include "gui/notifyqt.h" #include "util/QtVersion.h" /* Images for context menu icons */ #define IMAGE_CANCEL ":/images/delete.png" #define IMAGE_EDIT ":/images/edit_16.png" #define COLUMN_PATH 0 #define COLUMN_VIRTUALNAME 1 #define COLUMN_SHARE_FLAGS 2 #define COLUMN_GROUPS 3 ShareManager *ShareManager::_instance = NULL ; /** Default constructor */ ShareManager::ShareManager() : QDialog(NULL, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint) { /* Invoke Qt Designer generated QObject setup routine */ ui.setupUi(this); ui.headerFrame->setHeaderImage(QPixmap(":/images/fileshare64.png")); ui.headerFrame->setHeaderText(tr("Share Manager")); isLoading = false; Settings->loadWidgetInformation(this); connect(ui.addButton, SIGNAL(clicked( bool ) ), this , SLOT( addShare() ) ); connect(ui.closeButton, SIGNAL(clicked()), this, SLOT(applyAndClose())); connect(ui.cancelButton, SIGNAL(clicked()), this, SLOT(cancel())); connect(ui.shareddirList, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(shareddirListCustomPopupMenu(QPoint))); connect(ui.shareddirList, SIGNAL(cellDoubleClicked(int,int)), this, SLOT(doubleClickedCell(int,int))); connect(ui.shareddirList, SIGNAL(cellChanged(int,int)), this, SLOT(handleCellChange(int,int))); connect(NotifyQt::getInstance(), SIGNAL(groupsChanged(int)), this, SLOT(reload())); QHeaderView* header = ui.shareddirList->horizontalHeader(); QHeaderView_setSectionResizeModeColumn(header, COLUMN_PATH, QHeaderView::Stretch); header->setHighlightSections(false); setAcceptDrops(true); setAttribute(Qt::WA_DeleteOnClose, true); reload(); } void ShareManager::handleCellChange(int row,int column) { if(isLoading) return ; if(column == COLUMN_VIRTUALNAME) { // check if the thing already exists for(uint32_t i=0;iitem(i,COLUMN_VIRTUALNAME)->text().toUtf8()))) { ui.shareddirList->item(row,COLUMN_VIRTUALNAME)->setText(QString::fromUtf8(mDirInfos[row].virtualname.c_str())) ; return ; } mDirInfos[row].virtualname = std::string(ui.shareddirList->item(row,COLUMN_VIRTUALNAME)->text().toUtf8()) ; } } void ShareManager::editShareDirectory() { QTableWidget *listWidget = ui.shareddirList; int row = listWidget->currentRow(); int col = listWidget->currentColumn(); if(col == COLUMN_VIRTUALNAME) { QModelIndex index = ui.shareddirList->model()->index(row,col,QModelIndex()); ui.shareddirList->edit(index); } else doubleClickedCell(row,col) ; } void ShareManager::doubleClickedCell(int row,int column) { if(column == COLUMN_PATH) { QString dirname = QFileDialog::getExistingDirectory(NULL,tr("Choose directory"),QString(),QFileDialog::DontUseNativeDialog | QFileDialog::ShowDirsOnly); if(!dirname.isNull()) { std::string new_name( dirname.toUtf8() ); for(uint32_t i=0;i selected_groups = GroupSelectionDialog::selectGroups(mDirInfos[row].parent_groups) ; mDirInfos[row].parent_groups = selected_groups ; load(); } } ShareManager::~ShareManager() { _instance = NULL; Settings->saveWidgetInformation(this); } void ShareManager::cancel() { close(); } void ShareManager::applyAndClose() { // This is the only place where we change things. std::list infos ; for(uint32_t i=0;isetSharedDirectories(infos) ; close() ; } void ShareManager::shareddirListCustomPopupMenu( QPoint /*point*/ ) { QMenu contextMnu( this ); int col = ui.shareddirList->currentColumn(); QString edit_text ; switch(col) { case COLUMN_GROUPS: edit_text = tr("Change group visibility...") ; break ; case COLUMN_PATH: edit_text = tr("Choose directory to share...") ; break; case COLUMN_VIRTUALNAME: edit_text = tr("Choose visible name...") ; break; default: case COLUMN_SHARE_FLAGS: return ; } QAction *editAct = new QAction(QIcon(IMAGE_EDIT), edit_text, &contextMnu ); connect( editAct , SIGNAL( triggered() ), this, SLOT( editShareDirectory() ) ); QAction *removeAct = new QAction(QIcon(IMAGE_CANCEL), tr( "Remove" ), &contextMnu ); connect( removeAct , SIGNAL( triggered() ), this, SLOT( removeShareDirectory() ) ); contextMnu.addAction( editAct ); contextMnu.addAction( removeAct ); contextMnu.exec(QCursor::pos()); } void ShareManager::reload() { std::list dirs ; rsFiles->getSharedDirectories(dirs) ; mDirInfos.clear(); for(std::list::const_iterator it(dirs.begin());it!=dirs.end();++it) mDirInfos.push_back(*it) ; load(); } /** Loads the settings for this page */ void ShareManager::load() { if(isLoading) return ; isLoading = true; /* get a link to the table */ QTableWidget *listWidget = ui.shareddirList; /* set new row count */ listWidget->setRowCount(mDirInfos.size()); for(uint32_t row=0;rowsetItem(row, COLUMN_PATH, new QTableWidgetItem(QString::fromUtf8(mDirInfos[row].filename.c_str()))); if(mDirInfos[row].virtualname.empty()) listWidget->setItem(row, COLUMN_VIRTUALNAME, new QTableWidgetItem(tr("[Unset] (Double click to change)"))) ; else listWidget->setItem(row, COLUMN_VIRTUALNAME, new QTableWidgetItem(QString::fromUtf8(mDirInfos[row].virtualname.c_str()))); GroupFlagsWidget *widget = new GroupFlagsWidget(NULL,mDirInfos[row].shareflags); listWidget->setRowHeight(row, 32 * QFontMetricsF(font()).height()/14.0); listWidget->setCellWidget(row, COLUMN_SHARE_FLAGS, widget); listWidget->setItem(row, COLUMN_GROUPS, new QTableWidgetItem()) ; listWidget->item(row,COLUMN_GROUPS)->setBackgroundColor(QColor(183,236,181)) ; connect(widget,SIGNAL(flagsChanged(FileStorageFlags)),this,SLOT(updateFlags())) ; listWidget->item(row,COLUMN_GROUPS)->setToolTip(tr("Double click to select which groups of friends can see the files")) ; listWidget->item(row,COLUMN_VIRTUALNAME)->setToolTip(tr("Double click to change the name that friends will see.")) ; listWidget->item(row,COLUMN_GROUPS)->setText(getGroupString(mDirInfos[row].parent_groups)); QFont font = listWidget->item(row,COLUMN_GROUPS)->font(); font.setBold(mDirInfos[row].shareflags & DIR_FLAGS_BROWSABLE) ; listWidget->item(row,COLUMN_GROUPS)->setTextColor( (mDirInfos[row].shareflags & DIR_FLAGS_BROWSABLE)? (Qt::black):(Qt::lightGray)) ; listWidget->item(row,COLUMN_GROUPS)->setFont(font); if(QDir(QString::fromUtf8(mDirInfos[row].filename.c_str())).exists()) { listWidget->item(row,COLUMN_PATH)->setTextColor(Qt::black); listWidget->item(row,COLUMN_PATH)->setToolTip(tr("Double click to change shared directory path")) ; } else { listWidget->item(row,COLUMN_PATH)->setTextColor(Qt::lightGray); listWidget->item(row,COLUMN_PATH)->setToolTip(tr("Directory does not exist! Double click to change shared directory path")) ; } } listWidget->setColumnWidth(COLUMN_SHARE_FLAGS,132 * QFontMetricsF(font()).height()/14.0) ; listWidget->update(); /* update display */ update(); isLoading = false ; } void ShareManager::showYourself() { if(_instance == NULL) _instance = new ShareManager() ; _instance->reload() ; _instance->show() ; _instance->activateWindow(); } /*static*/ void ShareManager::postModDirectories(bool update_local) { if (_instance == NULL || _instance->isHidden()) { return; } if (update_local) { _instance->reload(); } } void ShareManager::updateFlags() { for(int row=0;rowrowCount();++row) { FileStorageFlags flags = (dynamic_cast(ui.shareddirList->cellWidget(row,COLUMN_SHARE_FLAGS)))->flags() ; mDirInfos[row].shareflags = flags ; } load() ; // update the GUI. } QString ShareManager::getGroupString(const std::list& groups) { if(groups.empty()) return tr("[All friend nodes]") ; int n = 0; QString group_string ; for (std::list::const_iterator it(groups.begin());it!=groups.end();++it,++n) { if (n>0) group_string += ", " ; RsGroupInfo groupInfo; rsPeers->getGroupInfo(*it, groupInfo); group_string += GroupDefs::name(groupInfo); } return group_string ; } void ShareManager::removeShareDirectory() { /* id current dir */ /* ask for removal */ QTableWidget *listWidget = ui.shareddirList; int row = listWidget -> currentRow(); QTableWidgetItem *qdir = listWidget->item(row, COLUMN_PATH); if (qdir) { if ((QMessageBox::question(this, tr("Warning!"),tr("Do you really want to stop sharing this directory ?"),QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes))== QMessageBox::Yes) { for(uint32_t i=row;i+1spontaneous()) { load(); } } void ShareManager::addShare() { QString fname = QFileDialog::getExistingDirectory(NULL,tr("Choose a directory to share"),QString(),QFileDialog::DontUseNativeDialog | QFileDialog::ShowDirsOnly); if(fname.isNull()) return; std::string dir_name ( fname.toUtf8() ); // check that the directory does not already exist for(uint32_t i=0;imimeData()->hasUrls()) { event->acceptProposedAction(); } } void ShareManager::dropEvent(QDropEvent *event) { if (!(Qt::CopyAction & event->possibleActions())) { /* can't do it */ return; } QStringList formats = event->mimeData()->formats(); QStringList::iterator it; bool errorShown = false; if (event->mimeData()->hasUrls()) { QList urls = event->mimeData()->urls(); QList::iterator it; for (it = urls.begin(); it != urls.end(); ++it) { QString localpath = it->toLocalFile(); if (localpath.isEmpty() == false) { QDir dir(localpath); if (dir.exists()) { SharedDirInfo sdi; sdi.filename = localpath.toUtf8().constData(); sdi.virtualname.clear(); sdi.shareflags.clear() ; /* add new share */ rsFiles->addSharedDirectory(sdi); } else if (QFile::exists(localpath)) { if (errorShown == false) { QMessageBox mb(tr("Drop file error."), tr("File can't be dropped, only directories are accepted."), QMessageBox::Information, QMessageBox::Ok, 0, 0, this); mb.exec(); errorShown = true; } } else { QMessageBox mb(tr("Drop file error."), tr("Directory not found or directory name not accepted."), QMessageBox::Information, QMessageBox::Ok, 0, 0, this); mb.exec(); } } } } event->setDropAction(Qt::CopyAction); event->accept(); load(); }