This commit is contained in:
defnax 2016-08-04 19:50:00 +02:00
commit 46d4863b09
36 changed files with 913 additions and 492 deletions

View File

@ -0,0 +1,70 @@
#include "ApiServerLocal.h"
#include "JsonStream.h"
namespace resource_api{
ApiServerLocal::ApiServerLocal(ApiServer* server) : QThread(),
mApiServer(server), mLocalServer(this)
{
start();
mLocalServer.removeServer(serverName());
#if QT_VERSION >= 0x050000
mLocalServer.setSocketOptions(QLocalServer::UserAccessOption);
#endif
connect(&mLocalServer, SIGNAL(newConnection()), this, SLOT(handleConnection()));
mLocalServer.listen(serverName());
}
ApiServerLocal::~ApiServerLocal()
{
mLocalServer.close();
quit();
}
void ApiServerLocal::handleConnection()
{
new ApiLocalConnectionHandler(mApiServer, mLocalServer.nextPendingConnection());
}
ApiLocalConnectionHandler::ApiLocalConnectionHandler(ApiServer* apiServer, QLocalSocket* sock) :
QThread(), mApiServer(apiServer), mLocalSocket(sock)
{
sock->moveToThread(this);
connect(this, SIGNAL(finished()), this, SLOT(deleteLater()));
connect(mLocalSocket, SIGNAL(disconnected()), this, SLOT(quit()));
connect(sock, SIGNAL(readyRead()), this, SLOT(handleRequest()));
start();
}
void ApiLocalConnectionHandler::handleRequest()
{
char path[1024];
if(mLocalSocket->readLine(path, 1023) > 0)
{
reqPath = path;
char jsonData[20480];
if(mLocalSocket->read(jsonData, 20479) > 0)
{
resource_api::JsonStream reqJson;
reqJson.setJsonString(std::string(jsonData));
resource_api::Request req(reqJson);
req.setPath(reqPath);
std::string resultString = mApiServer->handleRequest(req);
mLocalSocket->write(resultString.c_str(), resultString.length());
mLocalSocket->write("\n\0");
}
else mLocalSocket->write("\"{\"data\":null,\"debug_msg\":\"ApiLocalConnectionHandler::handleRequest() Error: timeout waiting for path.\\n\",\"returncode\":\"fail\"}\"\n\0");
}
else mLocalSocket->write("{\"data\":null,\"debug_msg\":\"ApiLocalConnectionHandler::handleRequest() Error: timeout waiting for JSON data.\\n\",\"returncode\":\"fail\"}\"\n\0");
quit();
}
ApiLocalConnectionHandler::~ApiLocalConnectionHandler()
{
mLocalSocket->flush();
mLocalSocket->close();
mLocalSocket->deleteLater();
}
} // namespace resource_api

View File

@ -0,0 +1,57 @@
#pragma once
#include <QLocalServer>
#include <QString>
#include <QThread>
#include <QLocalSocket>
#include <retroshare/rsinit.h>
#include <string>
#include "ApiServer.h"
namespace resource_api
{
class ApiServer;
class ApiServerLocal : public QThread
{
Q_OBJECT
public:
ApiServerLocal(ApiServer* server);
~ApiServerLocal();
public slots:
void handleConnection();
private:
ApiServer* mApiServer;
QLocalServer mLocalServer;
const static QString& serverName()
{
const static QString sockPath(RsAccounts::AccountDirectory()
.append("/libresapi.sock").c_str());
return sockPath;
}
};
class ApiLocalConnectionHandler : public QThread
{
Q_OBJECT
public:
ApiLocalConnectionHandler(ApiServer* apiServer, QLocalSocket* sock);
~ApiLocalConnectionHandler();
public slots:
void handleRequest();
private:
ApiServer* mApiServer;
QLocalSocket* mLocalSocket;
std::string reqPath;
void _die();
};
} // namespace resource_api

View File

@ -559,7 +559,7 @@ int ApiServerMHD::accessHandlerCallback(MHD_Connection *connection,
return ((MHDHandlerBase*)(*con_cls))->handleRequest(connection, url, method, version, upload_data, upload_data_size);
}
// these characters are not allowe in the url, raise an error if they occur
// these characters are not allowed in the url, raise an error if they occur
// reason: don't want to serve files outside the current document root
const char *double_dots = "..";
if(strstr(url, double_dots))

View File

@ -193,6 +193,33 @@ public:
// then each handler should pop the top element
std::stack<std::string> mPath;
std::string mFullPath;
bool setPath(std::string reqPath)
{
std::string str;
for(std::string::reverse_iterator sit = reqPath.rbegin(); sit != reqPath.rend(); sit++)
{
if((*sit) != '/')
{
// add to front because we are traveling in reverse order
str = *sit + str;
}
else
{
if(str != "")
{
mPath.push(str);
str.clear();
}
}
}
if(str != "")
{
mPath.push(str);
}
mFullPath = reqPath;
return true;
}
// parameters should be used to influence the result
// for example include or exclude some information

View File

@ -8,10 +8,11 @@ TARGET = resapi
TARGET_PRL = libresapi
DESTDIR = lib
CONFIG += libmicrohttpd
INCLUDEPATH += ../../libretroshare/src
libresapihttpserver {
CONFIG += libmicrohttpd
unix {
webui_files.path = "$${DATA_DIR}/webui"
@ -106,7 +107,6 @@ win32{
system($$MAKE_SRC\\init.bat .)
}
libmicrohttpd{
linux {
CONFIG += link_pkgconfig
PKGCONFIG *= libmicrohttpd
@ -173,3 +173,10 @@ HEADERS += \
util/ContentTypes.h \
api/ApiPluginHandler.h \
api/ChannelsHandler.h
libresapilocalserver {
CONFIG *= qt
QT *= network
SOURCES *= api/ApiServerLocal.cpp
HEADERS *= api/ApiServerLocal.h
}

View File

@ -712,8 +712,8 @@ int RsDataService::storeMessage(std::map<RsNxsMsg *, RsGxsMsgMetaData *> &msg)
// start a transaction
mDb->beginTransaction();
for(; mit != msg.end(); ++mit){
for(; mit != msg.end(); ++mit)
{
RsNxsMsg* msgPtr = mit->first;
RsGxsMsgMetaData* msgMetaPtr = mit->second;
@ -781,6 +781,10 @@ int RsDataService::storeMessage(std::map<RsNxsMsg *, RsGxsMsgMetaData *> &msg)
std::cerr << "\t & MessageId: " << msgMetaPtr->mMsgId.toStdString();
std::cerr << std::endl;
}
// This is needed so that mLastPost is correctly updated in the group meta when it is re-loaded.
locked_clearGrpMetaCache(msgMetaPtr->mGroupId);
}
// finish transaction

View File

@ -2019,6 +2019,9 @@ void RsGenExchange::publishMsgs()
delete[] metaDataBuff;
if(mNetService != NULL)
mNetService->stampMsgServerUpdateTS(grpId) ;
// add to published to allow acknowledgement
mMsgNotify.insert(std::make_pair(mit->first, std::make_pair(grpId, msgId)));
mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE);

View File

@ -595,6 +595,14 @@ public:
*/
void setGroupReputationCutOff(uint32_t& token, const RsGxsGroupId& grpId, int CutOff);
/*!
*
* @param token value set to be redeemed with acknowledgement
* @param grpId group id of the group to update
* @param CutOff The cut off value to set
*/
void updateGroupLastMsgTimeStamp(uint32_t& token, const RsGxsGroupId& grpId);
/*!
* @return storage time of messages in months
*/

View File

@ -2096,14 +2096,19 @@ void RsGxsNetService::updateServerSyncTS()
else
msui = mapIT->second;
if(grpMeta->mLastPost > msui->msgUpdateTS )
{
change = true;
msui->msgUpdateTS = grpMeta->mLastPost;
// (cyril) I'm removing this, because the msgUpdateTS is updated when new messages are received by calling locked_stampMsgServerUpdateTS().
// mLastPost is actually updated somewhere when loading group meta data. It's not clear yet whether it is set to the latest publish time (wrong)
// or the latest receive time (right). The former would cause problems because it would need to compare times coming from different (potentially async-ed)
// machines.
//
// if(grpMeta->mLastPost > msui->msgUpdateTS )
// {
// change = true;
// msui->msgUpdateTS = grpMeta->mLastPost;
#ifdef NXS_NET_DEBUG_0
GXSNETDEBUG__G(grpId) << " updated msgUpdateTS to last post = " << time(NULL) - grpMeta->mLastPost << " secs ago for group "<< grpId << std::endl;
// GXSNETDEBUG__G(grpId) << " updated msgUpdateTS to last post = " << time(NULL) - grpMeta->mLastPost << " secs ago for group "<< grpId << std::endl;
#endif
}
// }
// This is needed for group metadata updates to actually propagate: only a new grpUpdateTS will trigger the exchange of groups mPublishTs which
// will then be compared and pssibly trigger a MetaData transmission. mRecvTS is upated when creating, receiving for the first time, or receiving
@ -2123,6 +2128,7 @@ void RsGxsNetService::updateServerSyncTS()
if(change)
IndicateConfigChanged();
}
bool RsGxsNetService::locked_checkTransacTimedOut(NxsTransaction* tr)
{
return tr->mTimeOut < ((uint32_t) time(NULL));
@ -2595,6 +2601,8 @@ void RsGxsNetService::locked_processCompletedIncomingTrans(NxsTransaction* tr)
// for the grp id
locked_doMsgUpdateWork(tr->mTransaction, grpId);
// also update server sync TS, since we need to send the new message list to friends for comparison
locked_stampMsgServerUpdateTS(grpId);
}
}
else if(tr->mFlag == NxsTransaction::FLAG_STATE_FAILED)
@ -4891,3 +4899,26 @@ bool RsGxsNetService::getGroupServerUpdateTS(const RsGxsGroupId& gid,time_t& gro
return true ;
}
bool RsGxsNetService::stampMsgServerUpdateTS(const RsGxsGroupId& gid)
{
RS_STACK_MUTEX(mNxsMutex) ;
return locked_stampMsgServerUpdateTS(gid) ;
}
bool RsGxsNetService::locked_stampMsgServerUpdateTS(const RsGxsGroupId& gid)
{
std::map<RsGxsGroupId,RsGxsServerMsgUpdateItem*>::iterator it = mServerMsgUpdateMap.find(gid) ;
if(mServerMsgUpdateMap.end() == it)
{
RsGxsServerMsgUpdateItem *item = new RsGxsServerMsgUpdateItem(mServType);
item->grpId = gid ;
item->msgUpdateTS = time(NULL) ;
}
else
it->second->msgUpdateTS = time(NULL) ;
return true;
}

View File

@ -155,6 +155,7 @@ public:
virtual void rejectMessage(const RsGxsMessageId& msg_id) ;
virtual bool getGroupServerUpdateTS(const RsGxsGroupId& gid,time_t& grp_server_update_TS,time_t& msg_server_update_TS) ;
virtual bool stampMsgServerUpdateTS(const RsGxsGroupId& gid) ;
/* p3Config methods */
public:
@ -228,6 +229,13 @@ private:
*/
void locked_completeTransaction(NxsTransaction* trans);
/*!
* \brief locked_stampMsgServerUpdateTS
* updates the server msg time stamp. This function is the locked method for the one above with similar name
* \param gid group id to stamp.
* \return
*/
bool locked_stampMsgServerUpdateTS(const RsGxsGroupId& gid);
/*!
* This retrieves a unique transaction id that
* can be used in an outgoing transaction

View File

@ -144,6 +144,15 @@ public:
* \return false if the group is not found, true otherwise
*/
virtual bool getGroupServerUpdateTS(const RsGxsGroupId& gid,time_t& grp_server_update_TS,time_t& msg_server_update_TS) =0;
/*!
* \brief stampMsgServerUpdateTS
* Updates the msgServerUpdateMap structure to time(NULL), so as to trigger sending msg lists to friends.
* This is needed when e.g. posting a new message to a group.
* \param gid the group to stamp in msgServerUpdateMap
* \return
*/
virtual bool stampMsgServerUpdateTS(const RsGxsGroupId& gid) =0;
};
#endif // RSGNP_H

View File

@ -25,7 +25,7 @@
#include <stdio.h>
#ifndef WINDOWS_SYS
#if !defined(WINDOWS_SYS) && !defined(__ANDROID__)
#include <stdlib.h>
#include <execinfo.h>
@ -110,13 +110,13 @@ static inline void print_stacktrace(FILE *out = stderr, unsigned int max_frames
free(symbollist);
}
#else // WINDOWS_SYS
#else // !defined(WINDOWS_SYS) && !defined(__ANDROID__)
static inline void print_stacktrace(FILE *out = stderr, unsigned int max_frames = 63)
{
(void) max_frames;
fprintf(out, "TODO: 2016/01/01 print_stacktrace not implemented yet for WINDOWS_SYS\n");
fprintf(out, "TODO: 2016/01/01 print_stacktrace not implemented yet for WINDOWS_SYS and ANDROID\n");
}
#endif // WINDOWS_SYS
#endif // !defined(WINDOWS_SYS) && !defined(__ANDROID__)
#endif // _STACKTRACE_H_

View File

@ -29,7 +29,10 @@
#include <retroshare/rsdisc.h>
#include <retroshare/rspeers.h>
#include "settings/rsharesettings.h"
#ifdef ENABLE_WEBUI
#include <microhttpd.h>
#endif
#include <QClipboard>
#include <QSysInfo>
@ -781,11 +784,13 @@ void AboutDialog::on_copy_button_clicked()
RsControl::instance()->getLibraries(libraries);
verInfo+=addLibraries("libretroshare", libraries);
#ifdef ENABLE_WEBUI
/* Add version numbers of RetroShare */
// Add versions here. Find a better place.
libraries.clear();
libraries.push_back(RsLibraryInfo("Libmicrohttpd", MHD_get_version()));
verInfo+=addLibraries("RetroShare", libraries);
#endif // ENABLE_WEBUI
/* Add version numbers of plugins */
if (rsPlugins) {

View File

@ -23,6 +23,8 @@
#include <util/rsrandom.h>
#include <retroshare/rsinit.h>
#include <rsserver/rsaccounts.h>
#include "gui/settings/rsharesettings.h"
#include "util/misc.h"
#include "GenCertDialog.h"
#include <QAbstractEventDispatcher>
#include <QFileDialog>
@ -402,8 +404,8 @@ void GenCertDialog::exportIdentity()
{
QString fname = QFileDialog::getSaveFileName(this,tr("Export profile"), "",tr("RetroShare profile files (*.asc)")) ;
if(fname.isNull())
return ;
if(fname.isNull()) return ;
if(fname.right(4).toUpper() != ".ASC") fname += ".asc";
QVariant data = ui.genPGPuser->itemData(ui.genPGPuser->currentIndex());
RsPgpId gpg_id (data.toString().toStdString()) ;
@ -416,7 +418,9 @@ void GenCertDialog::exportIdentity()
void GenCertDialog::importIdentity()
{
QString fname = QFileDialog::getOpenFileName(this,tr("Import profile"), "",tr("RetroShare profile files (*.asc)")) ;
QString fname ;
if(!misc::getOpenFileName(this,RshareSettings::LASTDIR_CERT,tr("Import profile"), tr("RetroShare profile files (*.asc);;All files (*)"),fname))
return ;
if(fname.isNull())
return ;

View File

@ -24,7 +24,10 @@
#include <retroshare/rsiface.h>
#include <retroshare/rsplugin.h>
#ifdef ENABLE_WEBUI
#include <microhttpd.h>
#endif // ENABLE_WEBUI
#include <QFile>
#include <QTextStream>
@ -94,11 +97,13 @@ HelpDialog::HelpDialog(QWidget *parent) :
RsControl::instance()->getLibraries(libraries);
addLibraries(ui->libraryLayout, "libretroshare", libraries);
#ifdef ENABLE_WEBUI
/* Add version numbers of RetroShare */
// Add versions here. Find a better place.
libraries.clear();
libraries.push_back(RsLibraryInfo("Libmicrohttpd", MHD_get_version()));
addLibraries(ui->libraryLayout, "RetroShare", libraries);
#endif // ENABLE_WEBUI
/* Add version numbers of plugins */
if (rsPlugins) {

View File

@ -225,7 +225,6 @@ IdDialog::IdDialog(QWidget *parent) :
/* Add filter types */
QMenu *idTWHMenu = new QMenu(tr("Show"), this);
idTWHMenu->setVisible(true);
ui->idTreeWidget->addHeaderContextMenuMenu(idTWHMenu);
QActionGroup *idTWHActionGroup = new QActionGroup(this);

View File

@ -562,7 +562,9 @@ void MainWindow::createTrayIcon()
trayMenu->addSeparator();
trayMenu->addAction(QIcon(IMAGE_MESSENGER), tr("Open Messenger"), this, SLOT(showMessengerWindow()));
trayMenu->addAction(QIcon(IMAGE_MESSAGES), tr("Open Messages"), this, SLOT(showMess()));
#ifdef ENABLE_WEBUI
trayMenu->addAction(QIcon(":/images/emblem-web.png"), tr("Show web interface"), this, SLOT(showWebinterface()));
#endif // ENABLE_WEBUI
trayMenu->addAction(QIcon(IMAGE_BWGRAPH), tr("Bandwidth Graph"), _bandwidthGraph, SLOT(showWindow()));
trayMenu->addAction(QIcon(IMAGE_DHT), tr("Statistics"), this, SLOT(showStatisticsWindow()));
@ -1061,10 +1063,12 @@ void MainWindow::showStatisticsWindow()
StatisticsWindow::showYourself();
}
#ifdef ENABLE_WEBUI
void MainWindow::showWebinterface()
{
WebuiPage::showWebui();
}
#endif // ENABLE_WEBUI
/** Shows Application window */
#ifdef UNFINISHED

View File

@ -211,7 +211,9 @@ private slots:
void newRsCollection();
void showMessengerWindow();
void showStatisticsWindow();
#ifdef ENABLE_WEBUI
void showWebinterface();
#endif
//void servicePermission();
#ifdef UNFINISHED

View File

@ -20,6 +20,7 @@
****************************************************************/
#include "PluginManagerWidget.h"
#include "gui/settings/rsharesettings.h"
#include <QHBoxLayout>
#include <QVBoxLayout>
@ -160,15 +161,11 @@ PluginManagerWidget::registerNewPlugin(QString pluginName)
void
PluginManagerWidget::installPluginButtonClicked()
{
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open Plugin to install"),
"./",
tr("Plugins (*.so *.dll)"));
QString fileName = misc::getOpenFileName(this, RshareSettings::LASTDIR_PLUGIN, tr("Open Plugin to install"), "./", tr("Plugins (*.so *.dll)"));
if (!fileName.isNull())
{
emit installPluginRequested(fileName);
}
}
//=============================================================================

View File

@ -135,8 +135,15 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::Wi
RsGxsId current_id;
rsMsgs->getIdentityForChatLobby(lobbyId, current_id);
uint32_t idChooserFlag = IDCHOOSER_ID_REQUIRED;
ChatLobbyInfo lobbyInfo ;
if(rsMsgs->getChatLobbyInfo(lobbyId,lobbyInfo)) {
if (lobbyInfo.lobby_flags & RS_CHAT_LOBBY_FLAGS_PGP_SIGNED) {
idChooserFlag |= IDCHOOSER_NON_ANONYMOUS;
}
}
ownIdChooser = new GxsIdChooser() ;
ownIdChooser->loadIds(IDCHOOSER_ID_REQUIRED,current_id) ;
ownIdChooser->loadIds(idChooserFlag, current_id) ;
QWidgetAction *checkableAction = new QWidgetAction(this);
checkableAction->setDefaultWidget(ownIdChooser);
@ -281,8 +288,6 @@ void ChatLobbyDialog::init()
QString title;
std::list<ChatLobbyInfo>::const_iterator lobbyIt;
if(rsMsgs->getChatLobbyInfo(lobbyId,linfo))
{
title = QString::fromUtf8(linfo.lobby_name.c_str());

View File

@ -187,8 +187,9 @@ void FriendList::addToolButton(QToolButton *toolButton)
/* Initialize button */
toolButton->setAutoRaise(true);
toolButton->setIconSize(ui->displayButton->iconSize());
toolButton->setFocusPolicy(ui->displayButton->focusPolicy());
float S = QFontMetricsF(ui->filterLineEdit->font()).height() ;
toolButton->setIconSize(QSize(S*1.5,S*1.5));
toolButton->setFocusPolicy(Qt::NoFocus);
ui->titleBarFrame->layout()->addWidget(toolButton);
}
@ -1176,9 +1177,9 @@ void FriendList::insertPeers()
gpgItem->setData(COLUMN_NAME, ROLE_FILTER, gpgName);
gpgItem->setData(COLUMN_LAST_CONTACT, Qt::DisplayRole, showInfoAtGpgItem ? QVariant(bestLastContact) : "");
gpgItem->setData(COLUMN_LAST_CONTACT, ROLE_SORT_NAME, showInfoAtGpgItem ? QVariant(bestLastContact) : "");
gpgItem->setData(COLUMN_LAST_CONTACT, ROLE_SORT_NAME, QVariant(bestLastContact));
gpgItem->setText(COLUMN_IP, showInfoAtGpgItem ? bestIP : "");
gpgItem->setData(COLUMN_IP, ROLE_SORT_NAME, showInfoAtGpgItem ? bestIP : "");
gpgItem->setData(COLUMN_IP, ROLE_SORT_NAME, bestIP);
/* Sort data */
gpgItem->setData(COLUMN_NAME, ROLE_SORT_NAME, gpgName);
@ -2283,16 +2284,16 @@ void FriendList::addPeerToExpand(const std::string &gpgId)
void FriendList::createDisplayMenu()
{
QMenu *displayMenu = new QMenu(this);
QMenu *displayMenu = new QMenu(tr("Show"), this);
connect(displayMenu, SIGNAL(aboutToShow()), this, SLOT(updateMenu()));
displayMenu->addAction(ui->actionHideOfflineFriends);
displayMenu->addAction(ui->actionShowState);
displayMenu->addAction(ui->actionShowGroups);
displayMenu->addAction(ui->actionExportFriendlist);
displayMenu->addAction(ui->actionImportFriendlist);
ui->displayButton->setMenu(displayMenu);
ui->peerTreeWidget->addHeaderContextMenuMenu(displayMenu);
ui->peerTreeWidget->addHeaderContextMenuAction(ui->actionExportFriendlist);
ui->peerTreeWidget->addHeaderContextMenuAction(ui->actionImportFriendlist);
}
void FriendList::updateMenu()

View File

@ -53,38 +53,6 @@
<item>
<widget class="LineEditClear" name="filterLineEdit"/>
</item>
<item>
<widget class="QToolButton" name="displayButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>30</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="toolTip">
<string>Display</string>
</property>
<property name="icon">
<iconset resource="../images.qrc">
<normaloff>:/images/looknfeel.png</normaloff>:/images/looknfeel.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
<property name="autoRaise">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@ -188,8 +156,6 @@
<header>gui/common/RSTreeWidget.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../images.qrc"/>
</resources>
<resources/>
<connections/>
</ui>

View File

@ -160,6 +160,7 @@ RsCollectionDialog::RsCollectionDialog(const QString& collectionFileName
connect(ui._addRecur_PB, SIGNAL(clicked()), this, SLOT(addRecursive()));
connect(ui._remove_PB, SIGNAL(clicked()), this, SLOT(remove()));
connect(ui._makeDir_PB, SIGNAL(clicked()), this, SLOT(makeDir()));
connect(ui._removeDuplicate_CB, SIGNAL(clicked(bool)), this, SLOT(updateRemoveDuplicate(bool)));
connect(ui._cancel_PB, SIGNAL(clicked()), this, SLOT(cancel()));
connect(ui._save_PB, SIGNAL(clicked()), this, SLOT(save()));
connect(ui._download_PB, SIGNAL(clicked()), this, SLOT(download()));
@ -190,6 +191,7 @@ RsCollectionDialog::RsCollectionDialog(const QString& collectionFileName
// 5 Activate button follow creationMode
ui._changeFile->setVisible(_creationMode && !_readOnly);
ui._makeDir_PB->setVisible(_creationMode && !_readOnly);
ui._removeDuplicate_CB->setVisible(_creationMode && !_readOnly);
ui._save_PB->setVisible(_creationMode && !_readOnly);
ui._treeViewFrame->setVisible(_creationMode && !_readOnly);
ui._download_PB->setVisible(!_creationMode && !_readOnly);
@ -408,7 +410,10 @@ bool RsCollectionDialog::addChild(QTreeWidgetItem* parent, const std::vector<Col
if (colFileInfo.type == DIR_TYPE_DIR){
founds = ui._fileEntriesTW->findItems(colFileInfo.path + "/" +colFileInfo.name, Qt::MatchExactly | Qt::MatchRecursive, COLUMN_FILEPATH);
} else {
founds = ui._fileEntriesTW->findItems(colFileInfo.hash, Qt::MatchExactly | Qt::MatchRecursive, COLUMN_HASH);
founds = ui._fileEntriesTW->findItems(colFileInfo.path + "/" +colFileInfo.name, Qt::MatchExactly | Qt::MatchRecursive, COLUMN_FILEPATH);
if (ui._removeDuplicate_CB->isChecked()) {
founds << ui._fileEntriesTW->findItems(colFileInfo.hash, Qt::MatchExactly | Qt::MatchRecursive, COLUMN_HASH);
}
}
if (founds.empty()) {
QTreeWidgetItem *item = new QTreeWidgetItem;
@ -493,7 +498,8 @@ bool RsCollectionDialog::addChild(QTreeWidgetItem* parent, const std::vector<Col
if (colFileInfo.type == DIR_TYPE_DIR) {
wrong_chars |= addChild(founds.at(0), colFileInfo.children);
} }
}
}
}
return wrong_chars;
}
@ -827,9 +833,29 @@ void RsCollectionDialog::remove()
//msgBox->setInformativeText(); If text too long, no scroll, so I add an text edit
QGridLayout* layout = qobject_cast<QGridLayout*>(msgBox->layout());
if (layout) {
QTextEdit* edit = new QTextEdit(tr("Do you want to remove them and all their children, too? <br>") + listDir);
int newRow = 1;
for (int row = layout->count()-1; row >= 0; --row) {
for (int col = layout->columnCount()-1; col >= 0; --col) {
QLayoutItem *item = layout->itemAtPosition(row, col);
if (item) {
int index = layout->indexOf(item->widget());
int r=0, c=0, rSpan=0, cSpan=0;
layout->getItemPosition(index, &r, &c, &rSpan, &cSpan);
if (r>0) {
layout->removeItem(item);
layout->addItem(item, r+3, c, rSpan, cSpan);
} else if (rSpan>1) {
newRow = rSpan + 1;
}
}
}
}
QLabel *label = new QLabel(tr("Do you want to remove them and all their children, too?"));
layout->addWidget(label,newRow, 0, 1, layout->columnCount(), Qt::AlignHCenter );
QTextEdit *edit = new QTextEdit(listDir);
edit->setReadOnly(true);
layout->addWidget(edit,0 ,1);
edit->setWordWrapMode(QTextOption::NoWrap);
layout->addWidget(edit,newRow+1, 0, 1, layout->columnCount(), Qt::AlignHCenter );
}
msgBox->setStandardButtons(QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
@ -1063,6 +1089,79 @@ void RsCollectionDialog::itemChanged(QTreeWidgetItem *item, int col)
}
/**
* @brief RsCollectionDialog::updateRemoveDuplicate Remove all duplicate file when checked.
* @param checked
*/
void RsCollectionDialog::updateRemoveDuplicate(bool checked)
{
if (checked) {
QTreeWidgetItemIterator it(ui._fileEntriesTW);
QTreeWidgetItem *item;
while ((item = *it) != NULL) {
++it;
if (item->data(COLUMN_HASH, ROLE_TYPE).toUInt() != DIR_TYPE_DIR) {
QList<QTreeWidgetItem*> founds;
founds << ui._fileEntriesTW->findItems(item->text(COLUMN_HASH), Qt::MatchExactly | Qt::MatchRecursive, COLUMN_HASH);
if (founds.count() > 1) {
QMessageBox* msgBox = new QMessageBox(QMessageBox::Information, "", "");
msgBox->setText("Warning, duplicate file found.");
//msgBox->setInformativeText(); If text too long, no scroll, so I add an text edit
msgBox->setStandardButtons(QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
msgBox->setDefaultButton(QMessageBox::Yes);
QGridLayout* layout = qobject_cast<QGridLayout*>(msgBox->layout());
if (layout) {
int newRow = 1;
for (int row = layout->count()-1; row >= 0; --row) {
for (int col = layout->columnCount()-1; col >= 0; --col) {
QLayoutItem *item = layout->itemAtPosition(row, col);
if (item) {
int index = layout->indexOf(item->widget());
int r=0, c=0, rSpan=0, cSpan=0;
layout->getItemPosition(index, &r, &c, &rSpan, &cSpan);
if (r>0) {
layout->removeItem(item);
layout->addItem(item, r+3, c, rSpan, cSpan);
} else if (rSpan>1) {
newRow = rSpan + 1;
}
}
}
}
QLabel *label = new QLabel(tr("Do you want to remove this file from the list?"));
layout->addWidget(label,newRow, 0, 1, layout->columnCount(), Qt::AlignHCenter );
QTextEdit *edit = new QTextEdit(item->text(COLUMN_FILEPATH));
edit->setReadOnly(true);
edit->setWordWrapMode(QTextOption::NoWrap);
layout->addWidget(edit,newRow+1, 0, 1, layout->columnCount(), Qt::AlignHCenter );
}
int ret = msgBox->exec();
switch (ret) {
case QMessageBox::Yes:
item->parent()->removeChild(item);
break;
case QMessageBox::No:
break;
case QMessageBox::Cancel: {
delete msgBox;
ui._removeDuplicate_CB->setChecked(true);
return;
}
break;
default:
// should never be reached
break;
}
delete msgBox;
}
}
}
}
}
/**
* @brief RsCollectionDialog::cancel: Cancel RScollection editing or donwloading
*/

View File

@ -56,6 +56,7 @@ private slots:
void makeDir() ;
void fileHashingFinished(QList<HashedFile> hashedFiles) ;
void itemChanged(QTreeWidgetItem* item,int col) ;
void updateRemoveDuplicate(bool checked);
void cancel() ;
void download() ;
void save() ;

View File

@ -21,7 +21,16 @@
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
@ -59,7 +68,16 @@
<enum>QFrame::Plain</enum>
</property>
<layout class="QVBoxLayout">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@ -83,7 +101,16 @@
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@ -197,7 +224,16 @@
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@ -207,7 +243,16 @@
</property>
<widget class="QFrame" name="_treeViewFrame">
<layout class="QHBoxLayout">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@ -359,6 +404,13 @@
</item>
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QCheckBox" name="_removeDuplicate_CB">
<property name="text">
<string>Remove Duplicate</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
@ -405,12 +457,6 @@
</widget>
</item>
</layout>
<zorder></zorder>
<zorder></zorder>
<zorder>_mainSplitter</zorder>
<zorder>_listSplitter</zorder>
<zorder></zorder>
<zorder>_mainSplitter</zorder>
</widget>
</item>
</layout>

View File

@ -31,6 +31,8 @@
#include <QUrlQuery>
#endif
#include "gui/settings/rsharesettings.h"
#include "util/misc.h"
#include "ConnectFriendWizard.h"
#include "ui_ConnectFriendWizard.h"
#include "gui/common/PeerDefs.h"
@ -1040,7 +1042,9 @@ void ConnectFriendWizard::saveCert()
void ConnectFriendWizard::loadFriendCert()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Select Certificate"), "", tr("RetroShare Certificate (*.rsc );;All Files (*)"));
QString fileName ;
if(!misc::getOpenFileName(this, RshareSettings::LASTDIR_CERT, tr("Select Certificate"), tr("RetroShare Certificate (*.rsc );;All Files (*)"),fileName))
return ;
if (!fileName.isNull()) {
ui->friendFileNameEdit->setText(fileName);

View File

@ -24,7 +24,9 @@
#include <retroshare/rsinit.h>
#include <retroshare/rspeers.h>
#include "ProfileManager.h"
#include "util/misc.h"
#include "gui/GenCertDialog.h"
#include "gui/settings/rsharesettings.h"
#include "gui/common/RSTreeWidgetItem.h"
#include <QAbstractEventDispatcher>
@ -135,9 +137,7 @@ void ProfileManager::exportIdentity()
if (fname.isNull())
return;
if (QFileInfo(fname).suffix().isEmpty()) {
fname += ".asc";
}
if (fname.right(4).toUpper() != ".ASC") fname += ".asc";
if (RsAccounts::ExportIdentity(fname.toUtf8().constData(), gpgId))
QMessageBox::information(this, tr("Identity saved"), tr("Your identity was successfully saved\nIt is encrypted\n\nYou can now copy it to another computer\nand use the import button to load it"));
@ -147,7 +147,10 @@ void ProfileManager::exportIdentity()
void ProfileManager::importIdentity()
{
QString fname = QFileDialog::getOpenFileName(this,tr("Import Identity"), "",tr("RetroShare Identity files (*.asc)")) ;
QString fname ;
if(!misc::getOpenFileName(this,RshareSettings::LASTDIR_CERT,tr("Import Identity"), tr("RetroShare Identity files (*.asc)"),fname))
return ;
if(fname.isNull())
return ;

View File

@ -7,6 +7,7 @@
#include "api/ApiServer.h"
#include "api/ApiServerMHD.h"
#include "api/ApiServerLocal.h"
#include "api/RsControlModule.h"
#include "api/GetPluginInterfaces.h"
@ -14,6 +15,10 @@
resource_api::ApiServer* WebuiPage::apiServer = 0;
resource_api::ApiServerMHD* WebuiPage::apiServerMHD = 0;
// TODO: LIBRESAPI_LOCAL_SERVER Put indipendent option for libresapilocalserver in appropriate place
#ifdef LIBRESAPI_LOCAL_SERVER
resource_api::ApiServerLocal* WebuiPage::apiServerLocal = 0;
#endif
resource_api::RsControlModule* WebuiPage::controlModule = 0;
WebuiPage::WebuiPage(QWidget */*parent*/, Qt::WindowFlags /*flags*/)
@ -92,6 +97,11 @@ QString WebuiPage::helpText() const
"",
Settings->getWebinterfaceAllowAllIps());
apiServerMHD->start();
// TODO: LIBRESAPI_LOCAL_SERVER Move in appropriate place
#ifdef LIBRESAPI_LOCAL_SERVER
apiServerLocal = new resource_api::ApiServerLocal(apiServer);
#endif
return ok;
}
@ -102,6 +112,11 @@ QString WebuiPage::helpText() const
apiServerMHD->stop();
delete apiServerMHD;
apiServerMHD = 0;
// TODO: LIBRESAPI_LOCAL_SERVER Move in appropriate place
#ifdef LIBRESAPI_LOCAL_SERVER
delete apiServerLocal;
apiServerLocal = 0;
#endif
delete apiServer;
apiServer = 0;
delete controlModule;

View File

@ -6,6 +6,7 @@
namespace resource_api{
class ApiServer;
class ApiServerMHD;
class ApiServerLocal;
class RsControlModule;
}
@ -48,5 +49,8 @@ private:
static resource_api::ApiServer* apiServer;
static resource_api::ApiServerMHD* apiServerMHD;
#ifdef LIBRESAPI_LOCAL_SERVER
static resource_api::ApiServerLocal* apiServerLocal;
#endif
static resource_api::RsControlModule* controlModule;
};

View File

@ -152,8 +152,9 @@ RSettingsWin::initStackedWidget()
addPage(new AppearancePage());
addPage(new SoundPage() );
addPage(new ServicePermissionsPage() );
#ifdef ENABLE_WEBUI
addPage(new WebuiPage() );
#endif // ENABLE_WEBUI
// add widgets from plugins
for(int i=0;i<rsPlugins->nbPlugins();++i)

View File

@ -75,7 +75,8 @@ public:
LASTDIR_IMAGES,
LASTDIR_MESSAGES,
LASTDIR_BLOGS,
LASTDIR_SOUNDS
LASTDIR_SOUNDS,
LASTDIR_PLUGIN
};
enum enumToasterPosition

View File

@ -397,13 +397,17 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO);
notify->enable() ; // enable notification system after GUI creation, to avoid data races in Qt.
#ifdef ENABLE_WEBUI
WebuiPage::checkStartWebui();
#endif // ENABLE_WEBUI
/* dive into the endless loop */
int ti = rshare.exec();
delete w ;
#ifdef ENABLE_WEBUI
WebuiPage::checkShutdownWebui();
#endif // ENABLE_WEBUI
/* cleanup */
ChatDialog::cleanupChat();

View File

@ -551,7 +551,6 @@ HEADERS += rshare.h \
gui/connect/ConnectProgressDialog.h \
gui/groups/CreateGroup.h \
gui/GetStartedDialog.h \
gui/settings/WebuiPage.h \
gui/statistics/BWGraph.h \
util/RsSyntaxHighlighter.h \
util/imageutil.h
@ -671,7 +670,7 @@ FORMS += gui/StartDialog.ui \
gui/statistics/BwCtrlWindow.ui \
gui/statistics/RttStatistics.ui \
gui/GetStartedDialog.ui \
gui/settings/WebuiPage.ui
# gui/ForumsDialog.ui \
# gui/forums/CreateForum.ui \
@ -854,7 +853,6 @@ SOURCES += main.cpp \
gui/settings/ServicePermissionsPage.cpp \
gui/settings/AddFileAssociationDialog.cpp \
gui/settings/GroupFrameSettingsWidget.cpp \
gui/settings/WebuiPage.cpp \
gui/statusbar/peerstatus.cpp \
gui/statusbar/natstatus.cpp \
gui/statusbar/dhtstatus.cpp \
@ -1390,3 +1388,9 @@ gxsgui {
}
libresapihttpserver {
HEADERS *= gui/settings/WebuiPage.h
SOURCES *= gui/settings/WebuiPage.cpp
FORMS *= gui/settings/WebuiPage.ui
}

View File

@ -352,7 +352,7 @@ bool misc::getSaveFileName(QWidget *parent, RshareSettings::enumLastDir type
{
QString lastDir = Settings->getLastDir(type);
file = QFileDialog::getSaveFileName(parent, caption, lastDir, filter, selectedFilter, options);
file = QFileDialog::getSaveFileName(parent, caption, lastDir, filter, selectedFilter, QFileDialog::DontUseNativeDialog | options);
if (file.isEmpty())
return false;

View File

@ -5,8 +5,6 @@ TARGET = RetroShare06-nogui
CONFIG += bitdht
#CONFIG += introserver
#CONFIG += sshserver
# webinterface, requires libmicrohttpd
CONFIG += webui
CONFIG -= qt xml gui
CONFIG += link_prl
@ -184,7 +182,7 @@ introserver {
DEFINES *= RS_INTRO_SERVER
}
webui {
libresapihttpserver {
DEFINES *= ENABLE_WEBUI
PRE_TARGETDEPS *= ../../libresapi/src/lib/libresapi.a
LIBS += ../../libresapi/src/lib/libresapi.a

View File

@ -1,3 +1,10 @@
# To {dis,en}able libresapi via local socket (unix domain socket or windows named pipes)
# {,un}comment the following line
#CONFIG *= libresapilocalserver
# To {dis,en}able libresapi via HTTP (libmicrohttpd) {,un}comment the following line
CONFIG *= libresapihttpserver
# Gxs is always enabled now.
DEFINES *= RS_ENABLE_GXS
@ -10,6 +17,25 @@ unix {
isEmpty(PLUGIN_DIR) { PLUGIN_DIR = "$${LIB_DIR}/retroshare/extensions6" }
}
android-g++ {
DEFINES *= NO_SQLCIPHER
DEFINES *= "fopen64=fopen"
DEFINES *= "fseeko64=fseeko"
DEFINES *= "ftello64=ftello"
INCLUDEPATH *= $$NDK_TOOLCHAIN_PATH/sysroot/usr/include/
LIBS *= -L$$NDK_TOOLCHAIN_PATH/sysroot/usr/lib/
LIBS *= -lssl -lcrypto -lsqlite3 -lupnp -lixml
ANDROID_EXTRA_LIBS *= $$NDK_TOOLCHAIN_PATH/sysroot/usr/lib/libcrypto.so
ANDROID_EXTRA_LIBS *= $$NDK_TOOLCHAIN_PATH/sysroot/usr/lib/libssl.so
ANDROID_EXTRA_LIBS *= $$NDK_TOOLCHAIN_PATH/sysroot/usr/lib/libbz2.so
ANDROID_EXTRA_LIBS *= $$NDK_TOOLCHAIN_PATH/sysroot/usr/lib/libsqlite3.so
ANDROID_EXTRA_LIBS *= $$NDK_TOOLCHAIN_PATH/sysroot/usr/lib/libupnp.so
ANDROID_EXTRA_LIBS *= $$NDK_TOOLCHAIN_PATH/sysroot/usr/lib/libixml.so
message(NDK_TOOLCHAIN_PATH: $$NDK_TOOLCHAIN_PATH)
message(LIBS: $$LIBS)
message(ANDROID_EXTRA_LIBS: $$ANDROID_EXTRA_LIBS)
}
win32 {
message(***retroshare.pri:Win32)
exists($$PWD/../libs) {
@ -62,3 +88,6 @@ unfinished {
}
wikipoos:DEFINES *= RS_USE_WIKI
libresapilocalserver:DEFINES *= LIBRESAPI_LOCAL_SERVER
libresapihttpserver::DEFINES *= ENABLE_WEBUI