diff --git a/retroshare-gui/src/gui/AboutWidget.cpp b/retroshare-gui/src/gui/AboutWidget.cpp index b468550b1..1c4ae6827 100644 --- a/retroshare-gui/src/gui/AboutWidget.cpp +++ b/retroshare-gui/src/gui/AboutWidget.cpp @@ -142,7 +142,7 @@ void AboutWidget::updateTitle() { if (tWidget == NULL) { - setWindowTitle(QString("%1 %2").arg(tr("About RetroShare"), Rshare::retroshareVersion(true))); + setWindowTitle(QString("%1 %2").arg(tr("About RetroShare"), RsApplication::retroshareVersion(true))); } else { @@ -228,7 +228,7 @@ void AWidget::initImages() #ifdef RS_ONLYHIDDENNODE p.drawText(QPointF(10, 50), QString("%1 : %2 (With embedded Tor)").arg(tr("Retroshare version"), Rshare::retroshareVersion(true))); #else - p.drawText(QPointF(10, 50), QString("%1 : %2").arg(tr("Retroshare version"), Rshare::retroshareVersion(true))); + p.drawText(QPointF(10, 50), QString("%1 : %2").arg(tr("Retroshare version"), RsApplication::retroshareVersion(true))); #endif /* Draw Qt's version number */ @@ -936,7 +936,7 @@ void AboutWidget::on_copy_button_clicked() { QString verInfo; QString rsVerString = "RetroShare Version: "; - rsVerString+=Rshare::retroshareVersion(true); + rsVerString+=RsApplication::retroshareVersion(true); verInfo+=rsVerString; #ifdef RS_ONLYHIDDENNODE verInfo+=" " + tr("Only Hidden Node"); diff --git a/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp b/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp index 832970833..0223c1e7e 100644 --- a/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp +++ b/retroshare-gui/src/gui/FileTransfer/SearchDialog.cpp @@ -325,7 +325,7 @@ void SearchDialog::checkText(const QString& txt) ui.searchButton->setDisabled(txt.length() < 3); ui.searchLineFrame->setProperty("valid", (txt.length() >= 3)); ui.searchLineFrame->style()->unpolish(ui.searchLineFrame); - Rshare::refreshStyleSheet(ui.searchLineFrame, false); + RsApplication::refreshStyleSheet(ui.searchLineFrame, false); } void SearchDialog::initialiseFileTypeMappings() diff --git a/retroshare-gui/src/gui/GenCertDialog.cpp b/retroshare-gui/src/gui/GenCertDialog.cpp index d3b755f0d..f91ccac1b 100644 --- a/retroshare-gui/src/gui/GenCertDialog.cpp +++ b/retroshare-gui/src/gui/GenCertDialog.cpp @@ -649,7 +649,7 @@ void GenCertDialog::genPerson() { /* complete the process */ RsInit::LoadPassword(sslPasswd); - if (Rshare::loadCertificate(sslId, false)) { + if (RsApplication::loadCertificate(sslId, false)) { // Normally we should clear the cached passphrase as soon as possible. However,some other GUI components may still need it at start. // (csoler) This is really bad: we have to guess that 30 secs will be enough. I have no better way to do this. diff --git a/retroshare-gui/src/gui/GetStartedDialog.cpp b/retroshare-gui/src/gui/GetStartedDialog.cpp index e3bbd7170..399cc36d7 100644 --- a/retroshare-gui/src/gui/GetStartedDialog.cpp +++ b/retroshare-gui/src/gui/GetStartedDialog.cpp @@ -421,7 +421,7 @@ void GetStartedDialog::emailSupport() sysVersion = "Linux"; #endif #endif - text += QString("My RetroShare Configuration is: (%1, %2, %3)").arg(Rshare::retroshareVersion(true) + text += QString("My RetroShare Configuration is: (%1, %2, %3)").arg(RsApplication::retroshareVersion(true) , sysVersion ).arg(static_cast::type>(userLevel)) + "\n"; text += "\n"; diff --git a/retroshare-gui/src/gui/HelpDialog.cpp b/retroshare-gui/src/gui/HelpDialog.cpp index cc3f1d407..ddaf925d4 100644 --- a/retroshare-gui/src/gui/HelpDialog.cpp +++ b/retroshare-gui/src/gui/HelpDialog.cpp @@ -80,7 +80,7 @@ HelpDialog::HelpDialog(QWidget *parent) : ui->thanks->setHtml(in.readAll()); } - ui->version->setText(Rshare::retroshareVersion(true)); + ui->version->setText(RsApplication::retroshareVersion(true)); /* Add version numbers of libretroshare */ std::list libraries; diff --git a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp index ac9965d2a..7e5544413 100644 --- a/retroshare-gui/src/gui/Identity/IdEditDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdEditDialog.cpp @@ -703,7 +703,7 @@ void IdEditDialog::updateInterface() const QPixmap *pixmap = ui->avatarLabel->pixmap(); if (pixmap && !pixmap->isNull()) { ui->removeButton->setEnabled(true); - } else if (mEditGroup.mImage.mSize != NULL) { + } else if (mEditGroup.mImage.mSize > 0) { ui->removeButton->setEnabled(true); } else { ui->removeButton->setEnabled(false); diff --git a/retroshare-gui/src/gui/MainWindow.cpp b/retroshare-gui/src/gui/MainWindow.cpp index d69e2bb42..070f446e4 100644 --- a/retroshare-gui/src/gui/MainWindow.cpp +++ b/retroshare-gui/src/gui/MainWindow.cpp @@ -32,6 +32,7 @@ #include #include +#include #if defined(Q_OS_DARWIN) #include "gui/common/MacDockIconHandler.h" @@ -211,7 +212,7 @@ MainWindow::MainWindow(QWidget* parent, Qt::WindowFlags flags) hiddenmode = true; } - setWindowTitle(tr("RetroShare %1 a secure decentralized communication platform").arg(Rshare::retroshareVersion(true)) + " - " + nameAndLocation); + setWindowTitle(tr("RetroShare %1 a secure decentralized communication platform").arg(RsApplication::retroshareVersion(true)) + " - " + nameAndLocation); connect(rApp, SIGNAL(newArgsReceived(QStringList)), this, SLOT(receiveNewArgs(QStringList))); /* add url handler for RetroShare links */ @@ -1253,10 +1254,87 @@ void MainWindow::doQuit() rApp->quit(); } +// This method parses arguments passed by another process. All arguments +// except -r, -f, -o and lists of rscollection files and rslinks are discarded. +// void MainWindow::receiveNewArgs(QStringList args) { - Rshare::parseArguments(args, false); - processLastArgs(); + QString arg, argl, value; + std::vector argv; + for(auto l:args) + argv.push_back((const char *)l.data()); + + // This class does all the job at once: validate arguments, and parses them. + + std::vector links_and_files; + + argstream as(argv.size(),const_cast(argv.data())); + + QString omValues = QString(";full;noturtle;gaming;minimal;"); + std::string opModeStr; + std::string retroshare_link_url; + std::string rscollection_file; + + as >> parameter('r',"rslink",retroshare_link_url,"Retroshare:// link","Retroshare link to open in Downloads " ,false) + >> parameter('f',"rsfile",rscollection_file,"file","File to open " ,false) + >> parameter('o',"opmode",opModeStr,"opmode","Set mode (Full, NoTurtle, Gaming, Minimal) " ,false) + >> values(back_inserter(links_and_files),"links and files"); + + if(!as.isOk()) + { + RsErr() << "Error while parsing arguments:" ; + RsErr() << as.errorLog() ; + return; + } + if(!opModeStr.empty() && omValues.contains(";"+QString::fromStdString(opModeStr).toLower()+";")) + { + QString opmode = QString::fromStdString(opModeStr).toLower(); + //RsApplication::setOpMode(opModeStr.toLower()); // Do we need this?? + + if (opmode == "noturtle") + opModeStatus->setCurrentIndex(static_cast::type>(RsOpMode::NOTURTLE) - 1); + else if (opmode == "gaming") + opModeStatus->setCurrentIndex(static_cast::type>(RsOpMode::GAMING) - 1); + else if (opmode == "minimal") + opModeStatus->setCurrentIndex(static_cast::type>(RsOpMode::MINIMAL) - 1); + else if (opmode != "") + opModeStatus->setCurrentIndex(static_cast::type>(RsOpMode::FULL) - 1); + + opModeStatus->setOpMode(); + } + + // Sort all collected arguments into rscollection files and retroshare links, accordingly + + QStringList rscollection_files; + QList rslinks; + + auto sort = [&](const QString s) { + + if(QFile(s).exists() && s.endsWith(".rscollection")) + rscollection_files.append(QString::fromUtf8(rscollection_file.c_str())); + else if(s.startsWith("retroshare://")) + { + RetroShareLink link(s); + + if(link.valid()) + rslinks.push_back(link); + } + }; + + sort(QString::fromUtf8(rscollection_file.c_str())); + sort(QString::fromUtf8(retroshare_link_url.c_str())); + + for(auto s:links_and_files) + sort(QString::fromUtf8(s.c_str())); + + // Now handle links and rscollection files. + + for(auto file:rscollection_files) + if(file.endsWith(".rscollection")) + openRsCollection(file); + + for(auto link:rslinks) + retroshareLinkActivated(link.toUrl()); } void MainWindow::displayErrorMessage(int /*a*/,int /*b*/,const QString& error_msg) @@ -1633,35 +1711,6 @@ void MainWindow::openRsCollection(const QString &filename) void MainWindow::processLastArgs() { - while (!Rshare::links()->isEmpty()) { - std::cerr << "MainWindow::processLastArgs() : " << Rshare::links()->count() << std::endl; - /* Now use links from the command line, because no RetroShare was running */ - RetroShareLink link(Rshare::links()->takeFirst()); - if (link.valid()) { - retroshareLinkActivated(link.toUrl()); - } - } - while (!Rshare::files()->isEmpty()) { - /* Now use files from the command line, because no RetroShare was running */ - openRsCollection(Rshare::files()->takeFirst()); - } - /* Handle the -opmode options. */ - if (opModeStatus) { - QString opmode = Rshare::opmode().toLower(); - if (opmode == "noturtle") { - opModeStatus->setCurrentIndex(static_cast::type>(RsOpMode::NOTURTLE) - 1); - } else if (opmode == "gaming") { - opModeStatus->setCurrentIndex(static_cast::type>(RsOpMode::GAMING) - 1); - } else if (opmode == "minimal") { - opModeStatus->setCurrentIndex(static_cast::type>(RsOpMode::MINIMAL) - 1); - } else if (opmode != "") { - opModeStatus->setCurrentIndex(static_cast::type>(RsOpMode::FULL) - 1); - } - opModeStatus->setOpMode(); - } else { - std::cerr << "ERR: MainWindow::processLastArgs opModeStatus is not initialized."; - } - } void MainWindow::switchVisibilityStatus(StatusElement e,bool b) diff --git a/retroshare-gui/src/gui/PluginManager.cpp b/retroshare-gui/src/gui/PluginManager.cpp index 2b6fa01a6..e5ac7f7d5 100644 --- a/retroshare-gui/src/gui/PluginManager.cpp +++ b/retroshare-gui/src/gui/PluginManager.cpp @@ -41,7 +41,7 @@ PluginManager::PluginManager() { baseFolder = //qApp->applicationDirPath()+"///plugins" ; -Rshare::dataDirectory() + "/plugins" ; +RsApplication::dataDirectory() + "/plugins" ; lastError = "No error."; viewWidget = 0; diff --git a/retroshare-gui/src/gui/StartDialog.cpp b/retroshare-gui/src/gui/StartDialog.cpp index d6f9f707d..bc98527da 100644 --- a/retroshare-gui/src/gui/StartDialog.cpp +++ b/retroshare-gui/src/gui/StartDialog.cpp @@ -123,7 +123,7 @@ void StartDialog::loadPerson() rsNotify->cachePgpPassphrase(ui.password_input->text().toUtf8().constData()) ; rsNotify->setDisableAskPassword(true); - bool res = Rshare::loadCertificate(accountId, ui.autologin_checkbox->isChecked()) ; + bool res = RsApplication::loadCertificate(accountId, ui.autologin_checkbox->isChecked()) ; rsNotify->setDisableAskPassword(false); rsNotify->clearPgpPassphrase(); diff --git a/retroshare-gui/src/gui/common/AvatarWidget.cpp b/retroshare-gui/src/gui/common/AvatarWidget.cpp index e6d6d03d9..02151730a 100644 --- a/retroshare-gui/src/gui/common/AvatarWidget.cpp +++ b/retroshare-gui/src/gui/common/AvatarWidget.cpp @@ -121,7 +121,7 @@ void AvatarWidget::setFrameType(FrameType type) //refreshAvatarImage(); refreshStatus(); - Rshare::refreshStyleSheet(this, false); + RsApplication::refreshStyleSheet(this, false); } void AvatarWidget::setId(const ChatId &id) { @@ -174,7 +174,7 @@ void AvatarWidget::refreshStatus() case NO_FRAME: case NORMAL_FRAME: { - Rshare::refreshStyleSheet(this, false); + RsApplication::refreshStyleSheet(this, false); break; } case STATUS_FRAME: @@ -252,7 +252,7 @@ void AvatarWidget::updateStatus(int status) mPeerState = status; setEnabled(((uint32_t) status == RS_STATUS_OFFLINE) ? false : true); - Rshare::refreshStyleSheet(this, false); + RsApplication::refreshStyleSheet(this, false); } void AvatarWidget::updateAvatar(const QString &peerId) diff --git a/retroshare-gui/src/gui/common/FriendSelectionWidget.cpp b/retroshare-gui/src/gui/common/FriendSelectionWidget.cpp index 2e91ded27..4608d1796 100644 --- a/retroshare-gui/src/gui/common/FriendSelectionWidget.cpp +++ b/retroshare-gui/src/gui/common/FriendSelectionWidget.cpp @@ -127,7 +127,7 @@ FriendSelectionWidget::FriendSelectionWidget(QWidget *parent) ui->filterLineEdit->showFilterIcon(); /* Refresh style to have the correct text color */ - Rshare::refreshStyleSheet(this, false); + RsApplication::refreshStyleSheet(this, false); mEventHandlerId_identities = 0; rsEvents->registerEventsHandler( [this](std::shared_ptr event) { @@ -1225,7 +1225,7 @@ std::string FriendSelectionWidget::idFromItem(QTreeWidgetItem *item) return item->data(COLUMN_DATA, ROLE_ID).toString().toStdString(); } -void FriendSelectionWidget::sortByChecked(bool sort) +void FriendSelectionWidget::sortByChecked(bool) { mCompareRole->clear(); mCompareRole->setRole(COLUMN_NAME,ROLE_SORT_SELECTED); diff --git a/retroshare-gui/src/gui/help/browser/helpbrowser.cpp b/retroshare-gui/src/gui/help/browser/helpbrowser.cpp index b21ba2cc5..f062b908c 100644 --- a/retroshare-gui/src/gui/help/browser/helpbrowser.cpp +++ b/retroshare-gui/src/gui/help/browser/helpbrowser.cpp @@ -117,7 +117,7 @@ HelpBrowser::~HelpBrowser() QString HelpBrowser::language() { - QString lang = Rshare::language(); + QString lang = RsApplication::language(); if (!QDir(":/help/" + lang).exists()) lang = "en"; return lang; diff --git a/retroshare-gui/src/gui/help/browser/helptextbrowser.cpp b/retroshare-gui/src/gui/help/browser/helptextbrowser.cpp index a4b70058f..d9b012775 100644 --- a/retroshare-gui/src/gui/help/browser/helptextbrowser.cpp +++ b/retroshare-gui/src/gui/help/browser/helptextbrowser.cpp @@ -54,7 +54,7 @@ HelpTextBrowser::loadResource(int type, const QUrl &name) /* Fall back to English if there is no translation of the specified help * page in the current language. */ if (!name.path().contains("/")) { - QString language = Rshare::language(); + QString language = RsApplication::language(); if (!QDir(":/help/" + language).exists()) language = "en"; helpPath += language + "/"; diff --git a/retroshare-gui/src/gui/profile/ProfileWidget.cpp b/retroshare-gui/src/gui/profile/ProfileWidget.cpp index cf823ab53..670bb86c7 100644 --- a/retroshare-gui/src/gui/profile/ProfileWidget.cpp +++ b/retroshare-gui/src/gui/profile/ProfileWidget.cpp @@ -45,13 +45,13 @@ ProfileWidget::ProfileWidget(QWidget *parent, Qt::WindowFlags flags) connect(ui.CopyCertButton,SIGNAL(clicked()), this, SLOT(copyCert())); connect(ui.profile_Button,SIGNAL(clicked()), this, SLOT(profilemanager())); - ui.onLineSince->setText(DateTime::formatLongDateTime(Rshare::startupTime())); + ui.onLineSince->setText(DateTime::formatLongDateTime(RsApplication::startupTime())); } void ProfileWidget::showEvent ( QShowEvent * /*event*/ ) { /* set retroshare version */ - ui.version->setText(Rshare::retroshareVersion(true)); + ui.version->setText(RsApplication::retroshareVersion(true)); RsPeerDetails detail; if (rsPeers->getPeerDetails(rsPeers->getOwnId(),detail)) diff --git a/retroshare-gui/src/gui/settings/AppearancePage.cpp b/retroshare-gui/src/gui/settings/AppearancePage.cpp index 8ad086ae9..a96df209d 100755 --- a/retroshare-gui/src/gui/settings/AppearancePage.cpp +++ b/retroshare-gui/src/gui/settings/AppearancePage.cpp @@ -84,7 +84,7 @@ AppearancePage::AppearancePage(QWidget * parent, Qt::WindowFlags flags) } QMap styleSheets; - Rshare::getAvailableStyleSheets(styleSheets); + RsApplication::getAvailableStyleSheets(styleSheets); foreach (QString name, styleSheets.keys()) { ui.cmboStyleSheet->addItem(name, styleSheets[name]); @@ -136,7 +136,7 @@ void AppearancePage::updateInterfaceStyle() #ifndef QT_NO_CURSOR QApplication::setOverrideCursor(Qt::WaitCursor); #endif - Rshare::setStyle(ui.cmboStyle->currentText()); + RsApplication::setStyle(ui.cmboStyle->currentText()); Settings->setInterfaceStyle(ui.cmboStyle->currentText()); #ifndef QT_NO_CURSOR QApplication::restoreOverrideCursor(); @@ -152,7 +152,7 @@ void AppearancePage::loadStyleSheet(int index) #ifndef QT_NO_CURSOR QApplication::setOverrideCursor(Qt::WaitCursor); #endif - Rshare::loadStyleSheet(ui.cmboStyleSheet->itemData(index).toString()); + RsApplication::loadStyleSheet(ui.cmboStyleSheet->itemData(index).toString()); #ifndef QT_NO_CURSOR QApplication::restoreOverrideCursor(); #endif @@ -251,7 +251,7 @@ void AppearancePage::updateCmboToolButtonSize() // NotifyQt::getInstance()->notifySettingsChanged(); // } -void AppearancePage::updateStyle() { Rshare::setStyle(ui.cmboStyle->currentText()); } +void AppearancePage::updateStyle() { RsApplication::setStyle(ui.cmboStyle->currentText()); } /** Loads the settings for this page */ void AppearancePage::load() @@ -259,7 +259,7 @@ void AppearancePage::load() int index = ui.cmboLanguage->findData(Settings->getLanguageCode()); whileBlocking(ui.cmboLanguage)->setCurrentIndex(index); - index = ui.cmboStyle->findData(Rshare::style().toLower()); + index = ui.cmboStyle->findData(RsApplication::style().toLower()); whileBlocking(ui.cmboStyle)->setCurrentIndex(index); index = ui.cmboStyleSheet->findData(Settings->getSheetName()); diff --git a/retroshare-gui/src/gui/settings/CryptoPage.cpp b/retroshare-gui/src/gui/settings/CryptoPage.cpp index 6c171bb1a..26d7cecea 100755 --- a/retroshare-gui/src/gui/settings/CryptoPage.cpp +++ b/retroshare-gui/src/gui/settings/CryptoPage.cpp @@ -66,7 +66,7 @@ CryptoPage::CryptoPage(QWidget * parent, Qt::WindowFlags flags) ui.retroshareId_content_LB->hide(); ui.stackPageCertificate->hide(); - ui.onlinesince->setText(DateTime::formatLongDateTime(Rshare::startupTime())); + ui.onlinesince->setText(DateTime::formatLongDateTime(RsApplication::startupTime())); } #ifdef UNUSED_CODE @@ -111,7 +111,7 @@ void CryptoPage::showEvent ( QShowEvent * /*event*/ ) ui.retroshareId_content_LB->setText(QString::fromUtf8(invite.c_str())); /* set retroshare version */ - ui.version->setText(Rshare::retroshareVersion(true)); + ui.version->setText(RsApplication::retroshareVersion(true)); std::list ids; ids.clear(); diff --git a/retroshare-gui/src/gui/settings/rsharesettings.cpp b/retroshare-gui/src/gui/settings/rsharesettings.cpp index 28a29300c..e811acd4a 100644 --- a/retroshare-gui/src/gui/settings/rsharesettings.cpp +++ b/retroshare-gui/src/gui/settings/rsharesettings.cpp @@ -910,7 +910,7 @@ void RshareSettings::setUseLocalServer(bool value) { if (value != getUseLocalServer()) { setValue("UseLocalServer", value); - Rshare::updateLocalServer(); + RsApplication::updateLocalServer(); } } diff --git a/retroshare-gui/src/main.cpp b/retroshare-gui/src/main.cpp index 3bfec8696..2150c2f16 100644 --- a/retroshare-gui/src/main.cpp +++ b/retroshare-gui/src/main.cpp @@ -30,6 +30,9 @@ CrashStackTrace gCrashStackTrace; #include #include #include +#include +#include +#include #include #include "gui/common/FilesDefs.h" @@ -92,10 +95,10 @@ CrashStackTrace gCrashStackTrace; extern "C" { __declspec(dllexport) __cdecl BOOL _OPENSSL_isservice(void) { - DWORD sess; - if (ProcessIdToSessionId(GetCurrentProcessId(),&sess)) - return sess==0; - return FALSE; + DWORD sess; + if (ProcessIdToSessionId(GetCurrentProcessId(),&sess)) + return sess==0; + return FALSE; } } #endif @@ -107,147 +110,8 @@ __declspec(dllexport) __cdecl BOOL _OPENSSL_isservice(void) #include "gui/notifyqt.h" #include -static void displayWarningAboutDSAKeys() +static void showHelp(const argstream& as) { - std::map > unsupported_keys; - RsAccounts::GetUnsupportedKeys(unsupported_keys); - - if(unsupported_keys.empty()) - return ; - - QMessageBox msgBox; - - QString txt = QObject::tr("You appear to have nodes associated to DSA keys:"); - txt += "
    " ; - for(std::map >::const_iterator it(unsupported_keys.begin());it!=unsupported_keys.end();++it) - { - txt += "
  • " + QString::fromStdString(it->first) ; - txt += "
      " ; - - for(uint32_t i=0;isecond.size();++i) - txt += "
    • " + QString::fromStdString(it->second[i]) + "
    • " ; - - txt += "
    " ; - txt += "
  • " ; - } - txt += "
" ; - - msgBox.setText(txt) ; - msgBox.setInformativeText(QObject::tr("DSA keys are not yet supported by this version of RetroShare. All these nodes will be unusable. We're very sorry for that.")); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setDefaultButton(QMessageBox::Ok); - msgBox.setWindowIcon(FilesDefs::getIconFromQtResourcePath(":/icons/logo_128.png")); - - msgBox.exec(); -} - -#ifdef WINDOWS_SYS -#if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0) && QT_VERSION < QT_VERSION_CHECK (5, 3, 0) -QStringList filedialog_open_filenames_hook(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options) -{ - return QFileDialog::getOpenFileNames(parent, caption, dir, filter, selectedFilter, options | QFileDialog::DontUseNativeDialog); -} - -QString filedialog_open_filename_hook(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options) -{ - return QFileDialog::getOpenFileName(parent, caption, dir, filter, selectedFilter, options | QFileDialog::DontUseNativeDialog); -} - -QString filedialog_save_filename_hook(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options) -{ - return QFileDialog::getSaveFileName(parent, caption, dir, filter, selectedFilter, options | QFileDialog::DontUseNativeDialog); -} - -QString filedialog_existing_directory_hook(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options) -{ - return QFileDialog::getExistingDirectory(parent, caption, dir, options | QFileDialog::DontUseNativeDialog); -} -#endif -#endif - -int main(int argc, char *argv[]) -{ -#ifdef WINDOWS_SYS - // The current directory of the application is changed when using the native dialog on Windows - // This is a quick fix until libretroshare is using a absolute path in the portable Version -#if QT_VERSION >= QT_VERSION_CHECK (5, 3, 0) - // Do we need a solution in v0.6? -#endif -#if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0) && QT_VERSION < QT_VERSION_CHECK (5, 3, 0) - typedef QStringList (*_qt_filedialog_open_filenames_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options); - typedef QString (*_qt_filedialog_open_filename_hook) (QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options); - typedef QString (*_qt_filedialog_save_filename_hook) (QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options); - typedef QString (*_qt_filedialog_existing_directory_hook)(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options); - - extern Q_GUI_EXPORT _qt_filedialog_open_filename_hook qt_filedialog_open_filename_hook; - extern Q_GUI_EXPORT _qt_filedialog_open_filenames_hook qt_filedialog_open_filenames_hook; - extern Q_GUI_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook; - extern Q_GUI_EXPORT _qt_filedialog_existing_directory_hook qt_filedialog_existing_directory_hook; - - qt_filedialog_open_filename_hook = filedialog_open_filename_hook; - qt_filedialog_open_filenames_hook = filedialog_open_filenames_hook; - qt_filedialog_save_filename_hook = filedialog_save_filename_hook; - qt_filedialog_existing_directory_hook = filedialog_existing_directory_hook; -#endif -#if QT_VERSION < QT_VERSION_CHECK (5, 0, 0) - extern bool Q_GUI_EXPORT qt_use_native_dialogs; - qt_use_native_dialogs = false; -#endif - - { - /* Set the current directory to the application dir, - because the start dir with autostart from the registry run key is not the exe dir */ - QApplication app(argc, argv); - QDir::setCurrent(QCoreApplication::applicationDirPath()); - } -#endif -#ifdef SIGFPE_DEBUG -feenableexcept(FE_INVALID | FE_DIVBYZERO); -#endif - - QStringList args = char_array_to_stringlist(argv+1, argc-1); - - Q_INIT_RESOURCE(images); - Q_INIT_RESOURCE(icons); - - // This is needed to allocate rsNotify, so that it can be used to ask for PGP passphrase - // - RsControl::earlyInitNotificationSystem() ; - - NotifyQt *notify = NotifyQt::Create(); - rsNotify->registerNotifyClient(notify); - - /* RetroShare Core Objects */ - RsInit::InitRsConfig(); - - RsConfigOptions conf; - - argstream as(argc,argv); - as >> option('s',"stderr" ,conf.outStderr ,"output to stderr instead of log file " ) - >> option('u',"udp" ,conf.udpListenerOnly,"Only listen to UDP " ) - >> parameter('c',"base-dir" ,conf.optBaseDir ,"directory", "Set base directory " ,false) - >> parameter('l',"log-file" ,conf.logfname ,"logfile" ,"Set Log filename " ,false) - >> parameter('d',"debug-level" ,conf.debugLevel ,"level" ,"Set debug level " ,false) - >> parameter('i',"ip-address" ,conf.forcedInetAddress,"nnn.nnn.nnn.nnn", "Force IP address " ,false) - >> parameter('p',"port" ,conf.forcedPort ,"port" ,"Set listenning port " ,false) - >> parameter('o',"opmode" ,conf.opModeStr ,"opmode" ,"Set mode (Full, NoTurtle, Gaming, Minimal) " ,false) - >> parameter('t',"opmode" ,conf.userSuppliedTorExecutable,"tor" ,"supply full tor executable path " ,false); -#ifdef RS_JSONAPI - as >> parameter('J', "jsonApiPort", conf.jsonApiPort, "jsonApiPort", "Enable JSON API on the specified port", false ) - >> parameter('P', "jsonApiBindAddress", conf.jsonApiBindAddress, "jsonApiBindAddress", "JSON API Bind Address ", false); -#endif // ifdef RS_JSONAPI - -#ifdef LOCALNET_TESTING - as >> parameter('R',"restrict-port" ,portRestrictions ,"port1-port2","Apply port restriction " ,false); -#endif // ifdef LOCALNET_TESTING - -#ifdef RS_AUTOLOGIN - as >> option('a',"auto-login" ,conf.autoLogin ,"AutoLogin (Windows Only) + StartMinimised"); -#endif // ifdef RS_AUTOLOGIN - as >> help('h',"help",QObject::tr("Display this help").toStdString().c_str()); - - if(as.helpRequested()) - { RsInfo() << "\n" << "+================================================================+\n" "| o---o o |\n" @@ -258,6 +122,8 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO); std::cerr << as.usage(true) << std::endl; + char *argv[1]; + int argc=0; QApplication dummyApp (argc, argv); // needed for QMessageBox QMessageBox box; QString text = QString::fromUtf8(as.usage(true,false).c_str()); @@ -272,139 +138,410 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO); // now compute the size of text and set the size of the box. For the record, this doesn't work... box.setBaseSize( QSize(QFontMetricsF(font).width(text),QFontMetricsF(font).height()*text.count('\n')) ); box.exec(); +} + +static bool notifyRunningInstance() +{ + // Connect to the Local Server of the main process to notify it + // that a new process had been started + + QLocalSocket localSocket; + localSocket.connectToServer(QString(TARGET)); +#ifdef DEBUG + std::cerr << "RsApplication::RsApplication waitForConnected to other instance." << std::endl; +#endif + if( localSocket.waitForConnected(100) ) + { +#ifdef DEBUG + std::cerr << "RsApplication::RsApplication Connection etablished. Waiting for disconnection." << std::endl; +#endif + localSocket.waitForDisconnected(1000); + return true; + } + else + { +#ifdef DEBUG + std::cerr << "RsApplication::RsApplication failed to connect to other instance." << std::endl; +#endif + return false; + } +} + +static void sendArgsToRunningInstance(const QStringList& args) +{ + QString serverName = QString(TARGET); + + // load into shared memory + QBuffer buffer; + buffer.open(QBuffer::ReadWrite); + QDataStream out(&buffer); + out << args; + int size = buffer.size(); + + QSharedMemory newArgs; + newArgs.setKey(serverName + "_newArgs"); + if (newArgs.isAttached()) newArgs.detach(); + + if (!newArgs.create(size)) { + std::cerr << "(EE) RsApplication::RsApplication Unable to create shared memory segment of size:" + << size << " error:" << newArgs.errorString().toStdString() << "." << std::endl; +#ifdef Q_OS_UNIX + std::cerr << "Look with `ipcs -m` for nattch==0 segment. And remove it with `ipcrm -m 'shmid'`." << std::endl; + //No need for windows, as it removes shared segment directly even when crash. +#endif + newArgs.detach(); + ::exit(EXIT_FAILURE); + } + newArgs.lock(); + char *to = (char*)newArgs.data(); + const char *from = buffer.data().data(); + memcpy(to, from, qMin(newArgs.size(), size)); + newArgs.unlock(); + + std::cerr << "RsApplication::RsApplication waitForConnected to other instance." << std::endl; + if(notifyRunningInstance()) + { + newArgs.detach(); + std::cerr << "RsApplication::RsApplication Arguments was sended." << std::endl + << " To disable it, in Options - General - Misc," << std::endl + << " uncheck \"Use Local Server to get new Arguments\"." << std::endl; + ::exit(EXIT_SUCCESS); // Terminate the program using STDLib's exit function + } + else + std::cerr << "RsApplication::RsApplication failed to connect to other instance." << std::endl; + newArgs.detach(); +} + +static void displayWarningAboutDSAKeys() +{ + std::map > unsupported_keys; + RsAccounts::GetUnsupportedKeys(unsupported_keys); + + if(unsupported_keys.empty()) + return ; + + QMessageBox msgBox; + + QString txt = QObject::tr("You appear to have nodes associated to DSA keys:"); + txt += "
    " ; + for(std::map >::const_iterator it(unsupported_keys.begin());it!=unsupported_keys.end();++it) + { + txt += "
  • " + QString::fromStdString(it->first) ; + txt += "
      " ; + + for(uint32_t i=0;isecond.size();++i) + txt += "
    • " + QString::fromStdString(it->second[i]) + "
    • " ; + + txt += "
    " ; + txt += "
  • " ; + } + txt += "
" ; + + msgBox.setText(txt) ; + msgBox.setInformativeText(QObject::tr("DSA keys are not yet supported by this version of RetroShare. All these nodes will be unusable. We're very sorry for that.")); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setDefaultButton(QMessageBox::Ok); + msgBox.setWindowIcon(FilesDefs::getIconFromQtResourcePath(":/icons/logo_128.png")); + + msgBox.exec(); +} + +#ifdef WINDOWS_SYS +#if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0) && QT_VERSION < QT_VERSION_CHECK (5, 3, 0) +QStringList filedialog_open_filenames_hook(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options) +{ + return QFileDialog::getOpenFileNames(parent, caption, dir, filter, selectedFilter, options | QFileDialog::DontUseNativeDialog); +} + +QString filedialog_open_filename_hook(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options) +{ + return QFileDialog::getOpenFileName(parent, caption, dir, filter, selectedFilter, options | QFileDialog::DontUseNativeDialog); +} + +QString filedialog_save_filename_hook(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options) +{ + return QFileDialog::getSaveFileName(parent, caption, dir, filter, selectedFilter, options | QFileDialog::DontUseNativeDialog); +} + +QString filedialog_existing_directory_hook(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options) +{ + return QFileDialog::getExistingDirectory(parent, caption, dir, options | QFileDialog::DontUseNativeDialog); +} +#endif +#endif + +int main(int argc, char *argv[]) +{ +#ifdef WINDOWS_SYS + // The current directory of the application is changed when using the native dialog on Windows + // This is a quick fix until libretroshare is using a absolute path in the portable Version +#if QT_VERSION >= QT_VERSION_CHECK (5, 3, 0) + // Do we need a solution in v0.6? +#endif +#if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0) && QT_VERSION < QT_VERSION_CHECK (5, 3, 0) + typedef QStringList (*_qt_filedialog_open_filenames_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options); + typedef QString (*_qt_filedialog_open_filename_hook) (QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options); + typedef QString (*_qt_filedialog_save_filename_hook) (QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options); + typedef QString (*_qt_filedialog_existing_directory_hook)(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options); + + extern Q_GUI_EXPORT _qt_filedialog_open_filename_hook qt_filedialog_open_filename_hook; + extern Q_GUI_EXPORT _qt_filedialog_open_filenames_hook qt_filedialog_open_filenames_hook; + extern Q_GUI_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook; + extern Q_GUI_EXPORT _qt_filedialog_existing_directory_hook qt_filedialog_existing_directory_hook; + + qt_filedialog_open_filename_hook = filedialog_open_filename_hook; + qt_filedialog_open_filenames_hook = filedialog_open_filenames_hook; + qt_filedialog_save_filename_hook = filedialog_save_filename_hook; + qt_filedialog_existing_directory_hook = filedialog_existing_directory_hook; +#endif +#if QT_VERSION < QT_VERSION_CHECK (5, 0, 0) + extern bool Q_GUI_EXPORT qt_use_native_dialogs; + qt_use_native_dialogs = false; +#endif + + { + /* Set the current directory to the application dir, + because the start dir with autostart from the registry run key is not the exe dir */ + QApplication app(argc, argv); + QDir::setCurrent(QCoreApplication::applicationDirPath()); + } +#endif +#ifdef SIGFPE_DEBUG +feenableexcept(FE_INVALID | FE_DIVBYZERO); +#endif + + QStringList args = char_array_to_stringlist(argv+1, argc-1); + + Q_INIT_RESOURCE(images); + Q_INIT_RESOURCE(icons); + + // This is needed to allocate rsNotify, so that it can be used to ask for PGP passphrase + // + RsControl::earlyInitNotificationSystem() ; + + NotifyQt *notify = NotifyQt::Create(); + rsNotify->registerNotifyClient(notify); + + /* RetroShare Core Objects */ + RsInit::InitRsConfig(); + + RsGUIConfigOptions conf; +//#define ARG_RESET "reset" /**< Reset Rshare's saved settings. */ +//#define ARG_DATADIR "datadir" /**< Directory to use for data files. */ +//#define ARG_LOGFILE "logfile" /**< Location of our logfile. */ +//#define ARG_LOGLEVEL "loglevel" /**< Log verbosity. */ +//#define ARG_GUISTYLE "style" /**< Argument specfying GUI style. */ +//#define ARG_GUISTYLESHEET "stylesheet" /**< Argument specfying GUI style. */ +//#define ARG_LANGUAGE "lang" /**< Argument specifying language. */ +//#define ARG_OPMODE_L "opmode" /**< OpMode (Full, NoTurtle, Gaming, Minimal) */ +//#define ARG_RSLINK_S "r" /**< Open RsLink with protocol retroshare:// */ +//#define ARG_RSLINK_L "link" /**< Open RsLink with protocol retroshare:// */ +//#define ARG_RSFILE_S "f" /**< Open RsFile with or without arg. */ +//#define ARG_RSFILE_L "rsfile" /**< Open RsFile with or without arg. */ + + std::string rslink,rsfile; + std::list links_and_files; + std::string loglevel="off"; + std::string logfilename,language,guistyle,guistylesheetfile; + + argstream as(argc,argv); + as >> option( 's',"stderr" ,conf.outStderr ,"output to stderr instead of log file " ) + >> option( 'u',"udp" ,conf.udpListenerOnly ,"Only listen to UDP " ) + >> option( 'R',"reset" ,conf.optResetParams ,"reset retroshare parameters " ) + >> parameter('c',"base-dir" ,conf.optBaseDir ,"directory" ,"Set base directory " ,false) + >> parameter('l',"log-file" ,logfilename ,"logfile" ,"Set Log filename " ,false) + >> parameter('d',"debug-level" ,loglevel ,"level (debug,info,notice,warn,error,off)","Set debug level " ,false) + >> parameter('i',"ip-address" ,conf.forcedInetAddress ,"nnn.nnn.nnn.nnn" ,"Force IP address " ,false) + >> parameter('p',"port" ,conf.forcedPort ,"port" ,"Set listenning port " ,false) + >> parameter('o',"opmode" ,conf.opModeStr ,"opmode (Full, NoTurtle, Gaming, Minimal)","Set mode" ,false) + >> parameter('t',"tor" ,conf.userSuppliedTorExecutable,"tor" ,"supply full tor executable path " ,false) + >> parameter('g',"style" ,guistyle ,"style " ,"" ,false) + >> parameter('k',"style" ,guistylesheetfile ,"style sheet file" ,"gui stylesheet file" ,false) + >> parameter('L',"lang" ,language ,"langage" ,"language string" ,false) + >> parameter('r',"link" ,rslink ,"retroshare link" ,"retroshare link to open (passed to running server)" ,false) + >> parameter('f',"rsfile" ,rsfile ,"rsfile" ,"rsfile to open (passed to running server)" ,false); +#ifdef RS_JSONAPI + as >> parameter('J', "jsonApiPort" ,conf.jsonApiPort ,"jsonApiPort" ,"Enable JSON API on the specified port" ,false) + >> parameter('P', "jsonApiBindAddress",conf.jsonApiBindAddress ,"jsonApiBindAddress" ,"JSON API Bind Address " ,false); +#endif // ifdef RS_JSONAPI + +#ifdef LOCALNET_TESTING + as >> parameter('R',"restrict-port" ,portRestrictions ,"port1-port2","Apply port restriction " ,false); +#endif // ifdef LOCALNET_TESTING + +#ifdef RS_AUTOLOGIN + as >> option('a',"auto-login" ,conf.autoLogin ,"AutoLogin (Windows Only) + StartMinimised"); +#endif // ifdef RS_AUTOLOGIN + as >> values(std::back_inserter(links_and_files),"links and files") + >> help('h',"help",QObject::tr("Display this help").toStdString().c_str()); + + conf.logFileName = QString::fromStdString(logfilename); + conf.logLevel = QString::fromStdString(loglevel); // these will be checked when used in RsApplication + conf.guiStyle = QString::fromStdString(guistyle); // these will be checked when used in RsApplication + conf.guiStyleSheetFile = QString::fromUtf8(guistylesheetfile.c_str());// these will be checked when used in RsApplication + + if(as.helpRequested()) + { + showHelp(as); return 0; } + // Look for parameters to be transmitted to running server + + if((!rslink.empty() || !rsfile.empty() || !links_and_files.empty() || !conf.opModeStr.empty()) && notifyRunningInstance()) + { + QStringList args; + RsErr() << "Sending rscollection files, retroshare links and opmode parameters to the runnning retroshare server." ; + + if(!rslink.empty()) { args.push_back("-l"); args.push_back(QString::fromUtf8(rslink.c_str())); } + if(!rsfile.empty()) { args.push_back("-f"); args.push_back(QString::fromUtf8(rsfile.c_str())); } + + for(auto s:links_and_files) + args.push_back(QString::fromUtf8(s.c_str())); + + if(!conf.opModeStr.empty()) { args.push_back("-o"); args.push_back(QString::fromStdString(conf.opModeStr)); } + + sendArgsToRunningInstance(args); + return 0; + } + + // Now start RS login system + conf.main_executable_path = argv[0]; - int initResult = RsInit::InitRetroShare(conf); + int initResult = RsInit::InitRetroShare(conf); - if(initResult == RS_INIT_NO_KEYRING) // happens when we already have accounts, but no pgp key. This is when switching to the openpgp-sdk version. - { - QApplication dummyApp (argc, argv); // needed for QMessageBox - /* Translate into the desired language */ - LanguageSupport::translate(LanguageSupport::defaultLanguageCode()); + if(initResult == RS_INIT_NO_KEYRING) // happens when we already have accounts, but no pgp key. This is when switching to the openpgp-sdk version. + { + QApplication dummyApp (argc, argv); // needed for QMessageBox + /* Translate into the desired language */ + LanguageSupport::translate(LanguageSupport::defaultLanguageCode()); - QMessageBox msgBox; - msgBox.setText(QObject::tr("This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances.

You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software.")); - msgBox.setInformativeText(QObject::tr("Choose between:
  • Ok to copy the existing keyring from gnupg (safest bet), or
  • Close without saving to start fresh with an empty keyring (you will be asked to create a new PGP key to work with RetroShare, or import a previously saved pgp keypair).
  • Cancel to quit and forge a keyring by yourself (needs some PGP skills)
")); - msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Discard | QMessageBox::Cancel); - msgBox.setDefaultButton(QMessageBox::Ok); + QMessageBox msgBox; + msgBox.setText(QObject::tr("This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has it's own keyring shared by all RetroShare instances.

You do not appear to have such a keyring, although PGP keys are mentioned by existing RetroShare accounts, probably because you just changed to this new version of the software.")); + msgBox.setInformativeText(QObject::tr("Choose between:
  • Ok to copy the existing keyring from gnupg (safest bet), or
  • Close without saving to start fresh with an empty keyring (you will be asked to create a new PGP key to work with RetroShare, or import a previously saved pgp keypair).
  • Cancel to quit and forge a keyring by yourself (needs some PGP skills)
")); + msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Discard | QMessageBox::Cancel); + msgBox.setDefaultButton(QMessageBox::Ok); msgBox.setWindowIcon(FilesDefs::getIconFromQtResourcePath(":/icons/logo_128.png")); - int ret = msgBox.exec(); + int ret = msgBox.exec(); - if(ret == QMessageBox::Cancel) - return 0 ; - if(ret == QMessageBox::Ok) - { - if(!RsAccounts::CopyGnuPGKeyrings()) - return 0 ; + if(ret == QMessageBox::Cancel) + return 0 ; + if(ret == QMessageBox::Ok) + { + if(!RsAccounts::CopyGnuPGKeyrings()) + return 0 ; - initResult = RsInit::InitRetroShare(conf); + initResult = RsInit::InitRetroShare(conf); - displayWarningAboutDSAKeys() ; + displayWarningAboutDSAKeys() ; - } - else - initResult = RS_INIT_OK ; - } + } + else + initResult = RS_INIT_OK ; + } - if (initResult < 0) { - /* Error occured */ - QApplication dummyApp (argc, argv); // needed for QMessageBox - /* Translate into the desired language */ - LanguageSupport::translate(LanguageSupport::defaultLanguageCode()); + if (initResult < 0) { + /* Error occured */ + QApplication dummyApp (argc, argv); // needed for QMessageBox + /* Translate into the desired language */ + LanguageSupport::translate(LanguageSupport::defaultLanguageCode()); - displayWarningAboutDSAKeys(); + displayWarningAboutDSAKeys(); - QMessageBox mb(QMessageBox::Critical, QObject::tr("RetroShare"), "", QMessageBox::Ok); + QMessageBox mb(QMessageBox::Critical, QObject::tr("RetroShare"), "", QMessageBox::Ok); mb.setWindowIcon(FilesDefs::getIconFromQtResourcePath(":/icons/logo_128.png")); - switch (initResult) - { - case RS_INIT_AUTH_FAILED: - std::cerr << "RsInit::InitRetroShare AuthGPG::InitAuth failed" << std::endl; - mb.setText(QObject::tr("Initialization failed. Wrong or missing installation of PGP.")); - break; - default: - /* Unexpected return code */ - std::cerr << "RsInit::InitRetroShare unexpected return code " << initResult << std::endl; - mb.setText(QObject::tr("An unexpected error occurred. Please report 'RsInit::InitRetroShare unexpected return code %1'.").arg(initResult)); - break; - } - mb.exec(); - return 1; - } + switch (initResult) + { + case RS_INIT_AUTH_FAILED: + std::cerr << "RsInit::InitRetroShare AuthGPG::InitAuth failed" << std::endl; + mb.setText(QObject::tr("Initialization failed. Wrong or missing installation of PGP.")); + break; + default: + /* Unexpected return code */ + std::cerr << "RsInit::InitRetroShare unexpected return code " << initResult << std::endl; + mb.setText(QObject::tr("An unexpected error occurred. Please report 'RsInit::InitRetroShare unexpected return code %1'.").arg(initResult)); + break; + } + mb.exec(); + return 1; + } - /* create global settings object - path maybe wrong, when no profile exist - in this case it can be use only for default values */ - RshareSettings::Create (); + /* create global settings object + path maybe wrong, when no profile exist + in this case it can be use only for default values */ + RshareSettings::Create (); - /* Setup The GUI Stuff */ - Rshare rshare(args, argc, argv, QString::fromUtf8(RsAccounts::ConfigDirectory().c_str())); + /* Setup The GUI Stuff */ + //Rshare rshare(args, argc, argv, QString::fromUtf8(RsAccounts::ConfigDirectory().c_str())); + RsApplication rshare(conf); - /* Start RetroShare */ - QString sDefaultGXSIdToCreate = ""; - switch (initResult) { - case RS_INIT_OK: - { - /* Login Dialog */ - /* check for existing Certificate */ - bool genCert = false; - std::list accountIds; - if (RsAccounts::GetAccountIds(accountIds) && (accountIds.size() > 0)) - { - StartDialog sd; - if (sd.exec() == QDialog::Rejected) { - return 1; - } + /* Start RetroShare */ + QString sDefaultGXSIdToCreate = ""; + switch (initResult) { + case RS_INIT_OK: + { + /* Login Dialog */ + /* check for existing Certificate */ + bool genCert = false; + std::list accountIds; + if (RsAccounts::GetAccountIds(accountIds) && (accountIds.size() > 0)) + { + StartDialog sd; + if (sd.exec() == QDialog::Rejected) { + return 1; + } - /* if we're logged in */ - genCert = sd.requestedNewCert(); - } - else - { - genCert = true; - } + /* if we're logged in */ + genCert = sd.requestedNewCert(); + } + else + { + genCert = true; + } - if (genCert) - { - GenCertDialog gd(false); + if (genCert) + { + GenCertDialog gd(false); - if (gd.exec () == QDialog::Rejected) - return 1; + if (gd.exec () == QDialog::Rejected) + return 1; - sDefaultGXSIdToCreate = gd.getGXSNickname(); - } + sDefaultGXSIdToCreate = gd.getGXSNickname(); + } - //splashScreen.show(); - } - break; - case RS_INIT_HAVE_ACCOUNT: - { - //splashScreen.show(); - //splashScreen.showMessage(rshare.translate("SplashScreen", "Load profile"), Qt::AlignHCenter | Qt::AlignBottom); + //splashScreen.show(); + } + break; + case RS_INIT_HAVE_ACCOUNT: + { + //splashScreen.show(); + //splashScreen.showMessage(rshare.translate("SplashScreen", "Load profile"), Qt::AlignHCenter | Qt::AlignBottom); - RsPeerId preferredId; - RsAccounts::GetPreferredAccountId(preferredId); + RsPeerId preferredId; + RsAccounts::GetPreferredAccountId(preferredId); - // true: note auto-login is active - Rshare::loadCertificate(preferredId, true); - } - break; - default: - /* Unexpected return code */ - std::cerr << "RsInit::InitRetroShare unexpected return code " << initResult << std::endl; - QMessageBox::warning(0, QObject::tr("RetroShare"), QObject::tr("An unexpected error occured. Please report 'RsInit::InitRetroShare unexpected return code %1'.").arg(initResult)); - return 1; - } + // true: note auto-login is active + if(!RsApplication::loadCertificate(preferredId, true)) + { + RsErr() << "Retroshare auto-login startup failed." ; + return 1; + } + } + break; + default: + /* Unexpected return code */ + std::cerr << "RsInit::InitRetroShare unexpected return code " << initResult << std::endl; + QMessageBox::warning(0, QObject::tr("RetroShare"), QObject::tr("An unexpected error occured. Please report 'RsInit::InitRetroShare unexpected return code %1'.").arg(initResult)); + return 1; + } /* recreate global settings object, now with correct path, specific to the selected node */ - RshareSettings::Create(true); - Rshare::resetLanguageAndStyle(); + RshareSettings::Create(true); + RsApplication::resetLanguageAndStyle(); - SoundManager::create(); + SoundManager::create(); bool is_hidden_node = false; bool is_auto_tor = false ; @@ -413,15 +550,15 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO); RsAccounts::getCurrentAccountOptions(is_hidden_node,is_auto_tor,is_first_time); if(is_auto_tor) - { + { if(!conf.userSuppliedTorExecutable.empty()) RsTor::setTorExecutablePath(conf.userSuppliedTorExecutable); - // Now that we know the Tor service running, and we know the SSL id, we can make sure it provides a viable hidden service + // Now that we know the Tor service running, and we know the SSL id, we can make sure it provides a viable hidden service std::string tor_hidden_service_dir = RsAccounts::AccountDirectory() + "/hidden_service/" ; - RsTor::setTorDataDirectory(Rshare::dataDirectory().toStdString() + "/tor/"); + RsTor::setTorDataDirectory(RsApplication::dataDirectory().toStdString() + "/tor/"); RsTor::setHiddenServiceDirectory(tor_hidden_service_dir); // re-set it, because now it's changed to the specific location that is run RsDirUtil::checkCreateDirectory(std::string(tor_hidden_service_dir)) ; @@ -429,72 +566,72 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO); //RsTor::setupHiddenService(); if(! RsTor::start() || RsTor::hasError()) - { + { QMessageBox::critical(NULL,QObject::tr("Cannot start Tor Manager!"),QObject::tr("Tor cannot be started on your system: \n\n")+QString::fromStdString(RsTor::errorMessage())) ; - return 1 ; - } + return 1 ; + } - { + { TorControlDialog tcd; - QString error_msg ; - tcd.show(); + QString error_msg ; + tcd.show(); - while(tcd.checkForTor(error_msg) != TorControlDialog::TOR_STATUS_OK || tcd.checkForHiddenService() != TorControlDialog::HIDDEN_SERVICE_STATUS_OK) // runs until some status is reached: either tor works, or it fails. - { - QCoreApplication::processEvents(); - rstime::rs_usleep(0.2*1000*1000) ; + while(tcd.checkForTor(error_msg) != TorControlDialog::TOR_STATUS_OK || tcd.checkForHiddenService() != TorControlDialog::HIDDEN_SERVICE_STATUS_OK) // runs until some status is reached: either tor works, or it fails. + { + QCoreApplication::processEvents(); + rstime::rs_usleep(0.2*1000*1000) ; - if(!error_msg.isNull()) - { - QMessageBox::critical(NULL,QObject::tr("Cannot start Tor"),QObject::tr("Sorry but Tor cannot be started on your system!\n\nThe error reported is:\"")+error_msg+"\"") ; - return 1; - } - } + if(!error_msg.isNull()) + { + QMessageBox::critical(NULL,QObject::tr("Cannot start Tor"),QObject::tr("Sorry but Tor cannot be started on your system!\n\nThe error reported is:\"")+error_msg+"\"") ; + return 1; + } + } - tcd.hide(); + tcd.hide(); - if(tcd.checkForHiddenService() != TorControlDialog::HIDDEN_SERVICE_STATUS_OK) - { - QMessageBox::critical(NULL,QObject::tr("Cannot start a hidden tor service!"),QObject::tr("It was not possible to start a hidden service.")) ; - return 1 ; - } - } - } + if(tcd.checkForHiddenService() != TorControlDialog::HIDDEN_SERVICE_STATUS_OK) + { + QMessageBox::critical(NULL,QObject::tr("Cannot start a hidden tor service!"),QObject::tr("It was not possible to start a hidden service.")) ; + return 1 ; + } + } + } QSplashScreen splashScreen(FilesDefs::getPixmapFromQtResourcePath(":/images/logo/logo_splash.png")/* , Qt::WindowStaysOnTopHint*/); - splashScreen.show(); - splashScreen.showMessage(rshare.translate("SplashScreen", "Load configuration"), Qt::AlignHCenter | Qt::AlignBottom); + splashScreen.show(); + splashScreen.showMessage(rshare.translate("SplashScreen", "Load configuration"), Qt::AlignHCenter | Qt::AlignBottom); - QCoreApplication::processEvents(); + QCoreApplication::processEvents(); - /* stop Retroshare if startup fails */ - if (!RsControl::instance()->StartupRetroShare()) - { - std::cerr << "libretroshare failed to startup!" << std::endl; - return 1; - } + /* stop Retroshare if startup fails */ + if (!RsControl::instance()->StartupRetroShare()) + { + std::cerr << "libretroshare failed to startup!" << std::endl; + return 1; + } if(is_auto_tor) - { - // Tor works with viable hidden service. Let's use it! + { + // Tor works with viable hidden service. Let's use it! std::string service_id ; std::string onion_address ; - uint16_t service_port ; - uint16_t service_target_port ; - uint16_t proxy_server_port ; + uint16_t service_port ; + uint16_t service_target_port ; + uint16_t proxy_server_port ; std::string service_target_address ; std::string proxy_server_address ; RsTor::getHiddenServiceInfo(service_id,onion_address,service_port,service_target_address,service_target_port); RsTor::getProxyServerInfo(proxy_server_address,proxy_server_port) ; - std::cerr << "Got hidden service info: " << std::endl; + std::cerr << "Got hidden service info: " << std::endl; std::cerr << " onion address : " << onion_address << std::endl; std::cerr << " service_id : " << service_id << std::endl; - std::cerr << " service port : " << service_port << std::endl; - std::cerr << " target port : " << service_target_port << std::endl; + std::cerr << " service port : " << service_port << std::endl; + std::cerr << " target port : " << service_target_port << std::endl; std::cerr << " target address : " << service_target_address << std::endl; std::cerr << "Setting proxy server to " << service_target_address << ":" << service_target_port << std::endl; @@ -502,95 +639,95 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO); rsPeers->setLocalAddress(rsPeers->getOwnId(), service_target_address, service_target_port); rsPeers->setHiddenNode(rsPeers->getOwnId(), onion_address, service_port); rsPeers->setProxyServer(RS_HIDDEN_TYPE_TOR, proxy_server_address,proxy_server_port) ; - } + } - Rshare::initPlugins(); + RsApplication::initPlugins(); - splashScreen.showMessage(rshare.translate("SplashScreen", "Create interface"), Qt::AlignHCenter | Qt::AlignBottom); - QCoreApplication::processEvents(); // forces splashscreen to show up + splashScreen.showMessage(rshare.translate("SplashScreen", "Create interface"), Qt::AlignHCenter | Qt::AlignBottom); + QCoreApplication::processEvents(); // forces splashscreen to show up - RsharePeerSettings::Create(); + RsharePeerSettings::Create(); - Emoticons::load(); - AvatarDialog::load(); + Emoticons::load(); + AvatarDialog::load(); - if (Settings->value(QString::fromUtf8("FirstRun"), true).toBool()) { - splashScreen.hide(); + if (Settings->value(QString::fromUtf8("FirstRun"), true).toBool()) { + splashScreen.hide(); - Settings->setValue(QString::fromUtf8("FirstRun"), false); + Settings->setValue(QString::fromUtf8("FirstRun"), false); - SoundManager::initDefault(); + SoundManager::initDefault(); #ifdef __APPLE__ - /* For OSX, we set the default to "cleanlooks", as the AQUA style hides some input boxes - * only on the first run - as the user might want to change it ;) - */ - QString osx_style("cleanlooks"); - Rshare::setStyle(osx_style); - Settings->setInterfaceStyle(osx_style); + /* For OSX, we set the default to "cleanlooks", as the AQUA style hides some input boxes + * only on the first run - as the user might want to change it ;) + */ + QString osx_style("cleanlooks"); + Rshare::setStyle(osx_style); + Settings->setInterfaceStyle(osx_style); #endif // This is now disabled - as it doesn't add very much. // Need to make sure that defaults are sensible! #ifdef ENABLE_QUICKSTART_WIZARD - QuickStartWizard qstartWizard; - qstartWizard.exec(); + QuickStartWizard qstartWizard; + qstartWizard.exec(); #endif - } + } - MainWindow *w = MainWindow::Create (); - splashScreen.finish(w); + MainWindow *w = MainWindow::Create (); + splashScreen.finish(w); - w->processLastArgs(); + w->processLastArgs(); - if (!sDefaultGXSIdToCreate.isEmpty()) { - RsIdentityParameters params; - params.nickname = sDefaultGXSIdToCreate.toUtf8().constData(); - params.isPgpLinked = true; - params.mImage.clear(); - uint32_t token = 0; - rsIdentity->createIdentity(token, params); - } - // I'm using a signal to transfer the hashing info to the mainwindow, because Qt schedules signals properly to - // avoid clashes between infos from threads. - // + if (!sDefaultGXSIdToCreate.isEmpty()) { + RsIdentityParameters params; + params.nickname = sDefaultGXSIdToCreate.toUtf8().constData(); + params.isPgpLinked = true; + params.mImage.clear(); + uint32_t token = 0; + rsIdentity->createIdentity(token, params); + } + // I'm using a signal to transfer the hashing info to the mainwindow, because Qt schedules signals properly to + // avoid clashes between infos from threads. + // - qRegisterMetaType("RsPeerId") ; + qRegisterMetaType("RsPeerId") ; #ifdef DEBUG - std::cerr << "connecting signals and slots" << std::endl ; + std::cerr << "connecting signals and slots" << std::endl ; #endif - QObject::connect(notify,SIGNAL(deferredSignatureHandlingRequested()),notify,SLOT(handleSignatureEvent()),Qt::QueuedConnection) ; - QObject::connect(notify,SIGNAL(chatLobbyTimeShift(int)),notify,SLOT(handleChatLobbyTimeShift(int)),Qt::QueuedConnection) ; - QObject::connect(notify,SIGNAL(diskFull(int,int)) ,w ,SLOT(displayDiskSpaceWarning(int,int))) ; + QObject::connect(notify,SIGNAL(deferredSignatureHandlingRequested()),notify,SLOT(handleSignatureEvent()),Qt::QueuedConnection) ; + QObject::connect(notify,SIGNAL(chatLobbyTimeShift(int)),notify,SLOT(handleChatLobbyTimeShift(int)),Qt::QueuedConnection) ; + QObject::connect(notify,SIGNAL(diskFull(int,int)) ,w ,SLOT(displayDiskSpaceWarning(int,int))) ; QObject::connect(notify,SIGNAL(filesPostModChanged(bool)) ,w ,SLOT(postModDirectories(bool)) ,Qt::QueuedConnection ) ; - QObject::connect(notify,SIGNAL(transfersChanged()) ,w->transfersDialog ,SLOT(insertTransfers() )) ; - QObject::connect(notify,SIGNAL(publicChatChanged(int)) ,w->friendsDialog ,SLOT(publicChatChanged(int) )); - QObject::connect(notify,SIGNAL(neighboursChanged()) ,w->friendsDialog->networkDialog ,SLOT(securedUpdateDisplay())) ; + QObject::connect(notify,SIGNAL(transfersChanged()) ,w->transfersDialog ,SLOT(insertTransfers() )) ; + QObject::connect(notify,SIGNAL(publicChatChanged(int)) ,w->friendsDialog ,SLOT(publicChatChanged(int) )); + QObject::connect(notify,SIGNAL(neighboursChanged()) ,w->friendsDialog->networkDialog ,SLOT(securedUpdateDisplay())) ; - QObject::connect(notify,SIGNAL(chatStatusChanged(const QString&,const QString&,bool)),w->friendsDialog,SLOT(updatePeerStatusString(const QString&,const QString&,bool))); - QObject::connect(notify,SIGNAL(ownStatusMessageChanged()),w->friendsDialog,SLOT(loadmypersonalstatus())); + QObject::connect(notify,SIGNAL(chatStatusChanged(const QString&,const QString&,bool)),w->friendsDialog,SLOT(updatePeerStatusString(const QString&,const QString&,bool))); + QObject::connect(notify,SIGNAL(ownStatusMessageChanged()),w->friendsDialog,SLOT(loadmypersonalstatus())); // QObject::connect(notify,SIGNAL(logInfoChanged(const QString&)) ,w->friendsDialog->networkDialog,SLOT(setLogInfo(QString))) ; - QObject::connect(notify,SIGNAL(discInfoChanged()) ,w->friendsDialog->networkView,SLOT(update()),Qt::QueuedConnection) ; - QObject::connect(notify,SIGNAL(errorOccurred(int,int,const QString&)),w,SLOT(displayErrorMessage(int,int,const QString&))) ; + QObject::connect(notify,SIGNAL(discInfoChanged()) ,w->friendsDialog->networkView,SLOT(update()),Qt::QueuedConnection) ; + QObject::connect(notify,SIGNAL(errorOccurred(int,int,const QString&)),w,SLOT(displayErrorMessage(int,int,const QString&))) ; - w->installGroupChatNotifier(); + w->installGroupChatNotifier(); - /* only show window, if not startMinimized */ - if (RsInit::getStartMinimised() || Settings->getStartMinimized()) - { - splashScreen.close(); - } else { - w->show(); - } + /* only show window, if not startMinimized */ + if (RsInit::getStartMinimised() || Settings->getStartMinimized()) + { + splashScreen.close(); + } else { + w->show(); + } - /* Startup a Timer to keep the gui's updated */ - QTimer *timer = new QTimer(w); - timer -> connect(timer, SIGNAL(timeout()), notify, SLOT(UpdateGUI())); - timer->start(1000); + /* Startup a Timer to keep the gui's updated */ + QTimer *timer = new QTimer(w); + timer -> connect(timer, SIGNAL(timeout()), notify, SLOT(UpdateGUI())); + timer->start(1000); - notify->enable() ; // enable notification system after GUI creation, to avoid data races in Qt. + notify->enable() ; // enable notification system after GUI creation, to avoid data races in Qt. // Read webui params in settings. We cannot save them to some webui.cfg because cfg needs the node id and // jsonapi is started before node ID selection in retroshare-service. @@ -605,31 +742,31 @@ feenableexcept(FE_INVALID | FE_DIVBYZERO); RsInit::startupWebServices(conf,false); #endif - /* dive into the endless loop */ - int ti = rshare.exec(); - delete w ; + /* dive into the endless loop */ + int ti = rshare.exec(); + delete w ; #ifdef RS_JSONAPI - JsonApiPage::checkShutdownJsonApi(); + JsonApiPage::checkShutdownJsonApi(); #endif // RS_JSONAPI - /* cleanup */ - ChatDialog::cleanupChat(); + /* cleanup */ + ChatDialog::cleanupChat(); #ifdef RS_ENABLE_GXS - RsGxsUpdateBroadcast::cleanup(); + RsGxsUpdateBroadcast::cleanup(); #endif - if (is_auto_tor) { - RsTor::stop(); - } + if (is_auto_tor) { + RsTor::stop(); + } - RsControl::instance()->rsGlobalShutDown(); + RsControl::instance()->rsGlobalShutDown(); - delete(soundManager); - soundManager = NULL; + delete(soundManager); + soundManager = NULL; - Settings->sync(); - delete(Settings); + Settings->sync(); + delete(Settings); - return ti ; + return ti ; } diff --git a/retroshare-gui/src/rshare.cpp b/retroshare-gui/src/rshare.cpp index e5f450f57..65d0f5bea 100644 --- a/retroshare-gui/src/rshare.cpp +++ b/retroshare-gui/src/rshare.cpp @@ -50,6 +50,7 @@ #include #include +#include #include #include #include @@ -57,7 +58,7 @@ #include "rshare.h" /* Available command-line arguments. */ -#define ARG_RESET "reset" /**< Reset Rshare's saved settings. */ +#define ARG_RESET "reset" /**< Reset RsApplication's saved settings. */ #define ARG_DATADIR "datadir" /**< Directory to use for data files. */ #define ARG_LOGFILE "logfile" /**< Location of our logfile. */ #define ARG_LOGLEVEL "loglevel" /**< Log verbosity. */ @@ -86,19 +87,22 @@ static const char* const forwardableArgs[] = { }; /* Static member variables */ -QMap Rshare::_args; /**< List of command-line arguments. */ -Log Rshare::_log; /**< Logs debugging messages to file or stdout. */ -QString Rshare::_style; /**< The current GUI style. */ -QString Rshare::_stylesheet; /**< The current GUI stylesheet. */ -QString Rshare::_language; /**< The current language. */ -QString Rshare::_dateformat; /**< The format of dates in feed items etc. */ -QString Rshare::_opmode; /**< The operating mode passed by args. */ -QStringList Rshare::_links; /**< List of links passed by arguments. */ -QStringList Rshare::_files; /**< List of files passed by arguments. */ -QDateTime Rshare::mStartupTime; -bool Rshare::useConfigDir; -QString Rshare::configDir; -QLocalServer* Rshare::localServer; +#ifdef TO_REMOVE +QMap RsApplication::_args; /**< List of command-line arguments. */ +QString RsApplication::_style; /**< The current GUI style. */ +QString RsApplication::_stylesheet; /**< The current GUI stylesheet. */ +QString RsApplication::_language; /**< The current language. */ +QString RsApplication::_dateformat; /**< The format of dates in feed items etc. */ +QString RsApplication::_opmode; /**< The operating mode passed by args. */ +QStringList RsApplication::_links; /**< List of links passed by arguments. */ +QStringList RsApplication::_files; /**< List of files passed by arguments. */ +bool RsApplication::useConfigDir; +QString RsApplication::configDir; +#endif +Log RsApplication::log_output; /**< Logs debugging messages to file or stdout. */ +RsGUIConfigOptions RsApplication::options; +QDateTime RsApplication::mStartupTime; +QLocalServer* RsApplication::localServer; /** Catches debugging messages from Qt and sends them to RetroShare's logs. If Qt * emits a QtFatalMsg, we will write the message to the log and then abort(). @@ -133,194 +137,177 @@ void qt_msg_handler(QtMsgType type, const char *msg) } } -static bool notifyRunningInstance() -{ - // Connect to the Local Server of the main process to notify it - // that a new process had been started - QLocalSocket localSocket; - localSocket.connectToServer(QString(TARGET)); -#ifdef DEBUG - std::cerr << "Rshare::Rshare waitForConnected to other instance." << std::endl; -#endif - if( localSocket.waitForConnected(100) ) - { -#ifdef DEBUG - std::cerr << "Rshare::Rshare Connection etablished. Waiting for disconnection." << std::endl; -#endif - localSocket.waitForDisconnected(1000); - return true; - } - else - { -#ifdef DEBUG - std::cerr << "Rshare::Rshare failed to connect to other instance." << std::endl; -#endif - return false; - } -} - -/** Constructor. Parses the command-line arguments, resets Rshare's +/** Constructor. Parses the command-line arguments, resets RsApplication's * configuration (if requested), and sets up the GUI style and language - * translation. */ -Rshare::Rshare(QStringList args, int &argc, char **argv, const QString &dir) -: QApplication(argc, argv) + * translation. + * the const_cast below is truely horrible, but it allows to hide these unused argc/argv + * when initing RsApplication + */ + +RsApplication::RsApplication(const RsGUIConfigOptions& conf) +: QApplication(const_cast(&conf)->argc,const_cast(&conf)->argv) { - mStartupTime = QDateTime::currentDateTime(); - localServer = NULL; + mStartupTime = QDateTime::currentDateTime(); + localServer = NULL; + options = conf; - //Initialize connection to LocalServer to know if other process runs. - { - QString serverName = QString(TARGET); - - // check if another instance is running - bool haveRunningInstance = notifyRunningInstance(); - - bool sendArgsToRunningInstance = haveRunningInstance; - if(args.empty()) - sendArgsToRunningInstance = false; - // if we find non-forwardable args, start a new instance - for(int iCurs = 0; iCurs < args.size(); ++iCurs) +#ifdef TO_REMOVE + //Initialize connection to LocalServer to know if other process runs. { - const char* const* argit = forwardableArgs; - bool found = false; - while(*argit && iCurs < args.size()) - { - if(args.value(iCurs) == "-"+QString(*argit) || args.value(iCurs) == "--"+QString(*argit)) - { - found = true; - if(argNeedsValue(*argit)) - iCurs++; - } - argit++; - } - if(!found) + QString serverName = QString(TARGET); + + // check if another instance is running + bool haveRunningInstance = notifyRunningInstance(); + + bool sendArgsToRunningInstance = haveRunningInstance; + if(args.empty()) sendArgsToRunningInstance = false; - } + // if we find non-forwardable args, start a new instance + for(int iCurs = 0; iCurs < args.size(); ++iCurs) + { + const char* const* argit = forwardableArgs; + bool found = false; + while(*argit && iCurs < args.size()) + { + if(args.value(iCurs) == "-"+QString(*argit) || args.value(iCurs) == "--"+QString(*argit)) + { + found = true; + if(argNeedsValue(*argit)) + iCurs++; + } + argit++; + } + if(!found) + sendArgsToRunningInstance = false; + } - if (sendArgsToRunningInstance) { - // load into shared memory - QBuffer buffer; - buffer.open(QBuffer::ReadWrite); - QDataStream out(&buffer); - out << args; - int size = buffer.size(); + if (sendArgsToRunningInstance) { + // load into shared memory + QBuffer buffer; + buffer.open(QBuffer::ReadWrite); + QDataStream out(&buffer); + out << args; + int size = buffer.size(); - QSharedMemory newArgs; - newArgs.setKey(serverName + "_newArgs"); - if (newArgs.isAttached()) newArgs.detach(); + QSharedMemory newArgs; + newArgs.setKey(serverName + "_newArgs"); + if (newArgs.isAttached()) newArgs.detach(); - if (!newArgs.create(size)) { - std::cerr << "(EE) Rshare::Rshare Unable to create shared memory segment of size:" - << size << " error:" << newArgs.errorString().toStdString() << "." << std::endl; + if (!newArgs.create(size)) { + std::cerr << "(EE) RsApplication::RsApplication Unable to create shared memory segment of size:" + << size << " error:" << newArgs.errorString().toStdString() << "." << std::endl; #ifdef Q_OS_UNIX - std::cerr << "Look with `ipcs -m` for nattch==0 segment. And remove it with `ipcrm -m 'shmid'`." << std::endl; - //No need for windows, as it removes shared segment directly even when crash. + std::cerr << "Look with `ipcs -m` for nattch==0 segment. And remove it with `ipcrm -m 'shmid'`." << std::endl; + //No need for windows, as it removes shared segment directly even when crash. #endif - newArgs.detach(); - ::exit(EXIT_FAILURE); - } - newArgs.lock(); - char *to = (char*)newArgs.data(); - const char *from = buffer.data().data(); - memcpy(to, from, qMin(newArgs.size(), size)); - newArgs.unlock(); + newArgs.detach(); + ::exit(EXIT_FAILURE); + } + newArgs.lock(); + char *to = (char*)newArgs.data(); + const char *from = buffer.data().data(); + memcpy(to, from, qMin(newArgs.size(), size)); + newArgs.unlock(); - std::cerr << "Rshare::Rshare waitForConnected to other instance." << std::endl; - if(notifyRunningInstance()) - { - newArgs.detach(); - std::cerr << "Rshare::Rshare Arguments was sended." << std::endl - << " To disable it, in Options - General - Misc," << std::endl - << " uncheck \"Use Local Server to get new Arguments\"." << std::endl; - ::exit(EXIT_SUCCESS); // Terminate the program using STDLib's exit function - } - else - std::cerr << "Rshare::Rshare failed to connect to other instance." << std::endl; - newArgs.detach(); - } + std::cerr << "RsApplication::RsApplication waitForConnected to other instance." << std::endl; + if(notifyRunningInstance()) + { + newArgs.detach(); + std::cerr << "RsApplication::RsApplication Arguments was sended." << std::endl + << " To disable it, in Options - General - Misc," << std::endl + << " uncheck \"Use Local Server to get new Arguments\"." << std::endl; + ::exit(EXIT_SUCCESS); // Terminate the program using STDLib's exit function + } + else + std::cerr << "RsApplication::RsApplication failed to connect to other instance." << std::endl; + newArgs.detach(); + } - if(!haveRunningInstance) - { - // No main process exists - // Or started without arguments - // So we start a Local Server to listen for connections from new process - localServer= new QLocalServer(); - QObject::connect(localServer, SIGNAL(newConnection()), this, SLOT(slotConnectionEstablished())); - updateLocalServer(); - // clear out any old arguments (race condition?) - QSharedMemory newArgs; - newArgs.setKey(QString(TARGET) + "_newArgs"); - if(newArgs.attach(QSharedMemory::ReadWrite)) - newArgs.detach(); + if(!haveRunningInstance) + { + // No main process exists + // Or started without arguments + // So we start a Local Server to listen for connections from new process + localServer= new QLocalServer(); + QObject::connect(localServer, SIGNAL(newConnection()), this, SLOT(slotConnectionEstablished())); + updateLocalServer(); + // clear out any old arguments (race condition?) + QSharedMemory newArgs; + newArgs.setKey(QString(TARGET) + "_newArgs"); + if(newArgs.attach(QSharedMemory::ReadWrite)) + newArgs.detach(); + } } - } +#endif #if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0) - qInstallMessageHandler(qt_msg_handler); + qInstallMessageHandler(qt_msg_handler); #else - qInstallMsgHandler(qt_msg_handler); + qInstallMsgHandler(qt_msg_handler); #endif #ifndef __APPLE__ - /* set default window icon */ - setWindowIcon(FilesDefs::getIconFromQtResourcePath(":/icons/logo_128.png")); + /* set default window icon */ + setWindowIcon(FilesDefs::getIconFromQtResourcePath(":/icons/logo_128.png")); #endif - mBlink = true; - QTimer *timer = new QTimer(this); - timer->setInterval(500); - connect(timer, SIGNAL(timeout()), this, SLOT(blinkTimer())); - timer->start(); + mBlink = true; + QTimer *timer = new QTimer(this); + timer->setInterval(500); + connect(timer, SIGNAL(timeout()), this, SLOT(blinkTimer())); + timer->start(); - timer = new QTimer(this); - timer->setInterval(60000); - connect(timer, SIGNAL(timeout()), this, SIGNAL(minuteTick())); - timer->start(); + timer = new QTimer(this); + timer->setInterval(60000); + connect(timer, SIGNAL(timeout()), this, SIGNAL(minuteTick())); + timer->start(); - /* Read in all our command-line arguments. */ - parseArguments(args); +#ifdef TO_REMOVE + /* Read in all our command-line arguments. */ + parseArguments(args); +#endif - /* Check if we're supposed to reset our config before proceeding. */ - if (_args.contains(ARG_RESET)) { - Settings->reset(); - } - - /* Handle the -loglevel and -logfile options. */ - if (_args.contains(ARG_LOGFILE)) - _log.open(_args.value(ARG_LOGFILE)); - if (_args.contains(ARG_LOGLEVEL)) { - _log.setLogLevel(Log::stringToLogLevel( - _args.value(ARG_LOGLEVEL))); - if (!_args.contains(ARG_LOGFILE)) - _log.open(stdout); - } - if (!_args.contains(ARG_LOGLEVEL) && - !_args.contains(ARG_LOGFILE)) - _log.setLogLevel(Log::Off); + /* Check if we're supposed to reset our config before proceeding. */ + if (options.optResetParams) + { + RsInfo() << "Resetting Retroshare config parameters, as requested (option -R)"; + Settings->reset(); + } - /* config directory */ - useConfigDir = false; - if (dir != "") - { - setConfigDirectory(dir); - } + /* Handle the -loglevel and -logfile options. */ + if (options.logLevel != "Off") + { + if (!options.logFileName.isNull()) + log_output.open(options.logFileName); + else + log_output.open(stdout); - /** Initialize support for language translations. */ - //LanguageSupport::initialize(); + log_output.setLogLevel(Log::stringToLogLevel(options.logLevel)); + } - resetLanguageAndStyle(); +#ifdef TO_REMOVE + /* config directory */ + useConfigDir = false; + if (!conf.optBaseDir.empty()) + setConfigDirectory(QString::fromStdString(conf.optBaseDir)); +#endif - /* Switch off auto shutdown */ - setQuitOnLastWindowClosed ( false ); + /** Initialize support for language translations. */ + //LanguageSupport::initialize(); - /* Initialize GxsIdDetails */ - GxsIdDetails::initialize(); + resetLanguageAndStyle(); + + /* Switch off auto shutdown */ + setQuitOnLastWindowClosed ( false ); + + /* Initialize GxsIdDetails */ + GxsIdDetails::initialize(); } /** Destructor */ -Rshare::~Rshare() +RsApplication::~RsApplication() { /* Cleanup GxsIdDetails */ GxsIdDetails::cleanup(); @@ -334,7 +321,7 @@ Rshare::~Rshare() /** * @brief Executed when new instance connect command is sent to LocalServer */ -void Rshare::slotConnectionEstablished() +void RsApplication::slotConnectionEstablished() { QSharedMemory newArgs; newArgs.setKey(QString(TARGET) + "_newArgs"); @@ -346,7 +333,7 @@ void Rshare::slotConnectionEstablished() /* this is not an error. It just means we were notified to check newArgs, but none had been set yet. TODO: implement separate ping/take messages - std::cerr << "(EE) Rshare::slotConnectionEstablished() Unable to attach to shared memory segment." + std::cerr << "(EE) RsApplication::slotConnectionEstablished() Unable to attach to shared memory segment." << newArgs.errorString().toStdString() << std::endl; */ socket->close(); @@ -371,22 +358,22 @@ void Rshare::slotConnectionEstablished() emit newArgsReceived(args); while (!args.empty()) { - std::cerr << "Rshare::slotConnectionEstablished args:" << QString(args.takeFirst()).toStdString() << std::endl; + std::cerr << "RsApplication::slotConnectionEstablished args:" << QString(args.takeFirst()).toStdString() << std::endl; } } -QString Rshare::retroshareVersion(bool) { return RS_HUMAN_READABLE_VERSION; } +QString RsApplication::retroshareVersion(bool) { return RS_HUMAN_READABLE_VERSION; } /** Enters the main event loop and waits until exit() is called. The signal * running() will be emitted when the event loop has started. */ int -Rshare::run() +RsApplication::run() { QTimer::singleShot(0, rApp, SLOT(onEventLoopStarted())); return rApp->exec(); } -QDateTime Rshare::startupTime() +QDateTime RsApplication::startupTime() { return mStartupTime; } @@ -395,14 +382,15 @@ QDateTime Rshare::startupTime() * will emit the running() signal to indicate that the application's event * loop is running. */ void -Rshare::onEventLoopStarted() +RsApplication::onEventLoopStarted() { emit running(); } +#ifdef TO_REMOVE /** Display usage information regarding command-line arguments. */ /*void -Rshare::printUsage(QString errmsg) +RsApplication::printUsage(QString errmsg) { QTextStream out(stdout);*/ @@ -417,18 +405,18 @@ Rshare::printUsage(QString errmsg) /* And available options */ //out << endl << "Available Options:" << endl; - //out << "\t-"ARG_RESET"\t\tResets ALL stored Rshare settings." << endl; - //out << "\t-"ARG_DATADIR"\tSets the directory Rshare uses for data files"<< endl; - //out << "\t-"ARG_GUISTYLE"\t\tSets Rshare's interface style." << endl; - //out << "\t-"ARG_GUISTYLESHEET"\t\tSets Rshare's stylesheet." << endl; + //out << "\t-"ARG_RESET"\t\tResets ALL stored RsApplication settings." << endl; + //out << "\t-"ARG_DATADIR"\tSets the directory RsApplication uses for data files"<< endl; + //out << "\t-"ARG_GUISTYLE"\t\tSets RsApplication's interface style." << endl; + //out << "\t-"ARG_GUISTYLESHEET"\t\tSets RsApplication's stylesheet." << endl; //out << "\t\t\t[" << QStyleFactory::keys().join("|") << "]" << endl; - //out << "\t-"ARG_LANGUAGE"\t\tSets Rshare's language." << endl; + //out << "\t-"ARG_LANGUAGE"\t\tSets RsApplication's language." << endl; //out << "\t\t\t[" << LanguageSupport::languageCodes().join("|") << "]" << endl; //} /** Displays usage information for command-line args. */ void -Rshare::showUsageMessageBox() +RsApplication::showUsageMessageBox() { QString usage; QTextStream out(&usage); @@ -469,7 +457,7 @@ Rshare::showUsageMessageBox() /** Returns true if the specified argument expects a value. */ bool -Rshare::argNeedsValue(const QString &argName) +RsApplication::argNeedsValue(const QString &argName) { return ( argName == ARG_DATADIR || @@ -489,9 +477,12 @@ Rshare::argNeedsValue(const QString &argName) /** Parses the list of command-line arguments for their argument names and * values. */ void -Rshare::parseArguments(QStringList args, bool firstRun) +RsApplication::parseArguments(QStringList args, bool firstRun) { QString arg, argl, value; + std::vector argv; + for(auto l:args) + argv.push_back((const char *)l.data()); /* Loop through all command-line args/values and put them in a map */ for (int iCurs = 0; iCurs < args.size(); ++iCurs) { @@ -539,11 +530,12 @@ Rshare::parseArguments(QStringList args, bool firstRun) _args.insert(arg, value); } } + } /** Verifies that all specified arguments were valid. */ bool -Rshare::validateArguments(QString &errmsg) +RsApplication::validateArguments(QString &errmsg) { /* Check for a writable log file */ if (_args.contains(ARG_LOGFILE) && !_log.isOpen()) { @@ -585,13 +577,14 @@ Rshare::validateArguments(QString &errmsg) } return true; } +#endif /** Sets the translation RetroShare will use. If one was specified on the * command-line, we will use that. Otherwise, we'll check to see if one was * saved previously. If not, we'll default to one appropriate for the system * locale. */ bool -Rshare::setLanguage(QString languageCode) +RsApplication::setLanguage(QString languageCode) { /* If the language code is empty, use the previously-saved setting */ if (languageCode.isEmpty()) { @@ -599,7 +592,7 @@ Rshare::setLanguage(QString languageCode) } /* Translate into the desired language */ if (LanguageSupport::translate(languageCode)) { - _language = languageCode; + options.language = languageCode; return true; } return false; @@ -610,7 +603,7 @@ Rshare::setLanguage(QString languageCode) * saved previously. If not, we'll default to the system * locale. */ bool -Rshare::setLocale(QString languageCode) +RsApplication::setLocale(QString languageCode) { bool retVal = false; /* If the language code is empty, use the previously-saved setting */ @@ -626,20 +619,20 @@ Rshare::setLocale(QString languageCode) } /** customize date format for feeds etc. */ -void Rshare::customizeDateFormat() +void RsApplication::customizeDateFormat() { QLocale locale = QLocale(); // set to default locale /* get long date format without weekday */ - _dateformat = locale.dateFormat(QLocale::LongFormat); - _dateformat.replace(QRegExp("^dddd,*[^ ]* *('[^']+' )*"), ""); - _dateformat.replace(QRegExp(",* *dddd"), ""); - _dateformat = _dateformat.trimmed(); + options.dateformat = locale.dateFormat(QLocale::LongFormat); + options.dateformat.replace(QRegExp("^dddd,*[^ ]* *('[^']+' )*"), ""); + options.dateformat.replace(QRegExp(",* *dddd"), ""); + options.dateformat = options.dateformat.trimmed(); } /** Get custom date format (defaultlongformat) */ -QString Rshare::customDateFormat() +QString RsApplication::customDateFormat() { - return _dateformat; + return options.dateformat; } /** Sets the GUI style RetroShare will use. If one was specified on the @@ -647,49 +640,50 @@ QString Rshare::customDateFormat() * saved previously. If not, we'll default to one appropriate for the * operating system. */ bool -Rshare::setStyle(QString styleKey) +RsApplication::setStyle(QString styleKey) { /* If no style was specified, use the previously-saved setting */ if (styleKey.isEmpty()) { styleKey = Settings->getInterfaceStyle(); } /* Apply the specified GUI style */ - if (QApplication::setStyle(styleKey)) { - _style = styleKey; + if (QApplication::setStyle(styleKey)) + { + options.guiStyle = styleKey; return true; } return false; } bool -Rshare::setSheet(QString sheet) +RsApplication::setSheet(QString sheet) { /* If no stylesheet was specified, use the previously-saved setting */ if (sheet.isEmpty()) { sheet = Settings->getSheetName(); } /* Apply the specified GUI stylesheet */ - _stylesheet = sheet; + options.guiStyleSheetFile = sheet; /* load the StyleSheet*/ - loadStyleSheet(_stylesheet); + loadStyleSheet(options.guiStyleSheetFile); return true; } -void Rshare::resetLanguageAndStyle() +void RsApplication::resetLanguageAndStyle() { /** Translate the GUI to the appropriate language. */ - setLanguage(_args.value(ARG_LANGUAGE)); + setLanguage(options.language); /** Set the locale appropriately. */ - setLocale(_args.value(ARG_LANGUAGE)); + setLocale(options.language); /** Set the GUI style appropriately. */ - setStyle(_args.value(ARG_GUISTYLE)); + setStyle(options.guiStyle); /** Set the GUI stylesheet appropriately. */ - setSheet(_args.value(ARG_GUISTYLESHEET)); + setSheet(options.guiStyleSheetFile); } // RetroShare: @@ -714,7 +708,7 @@ void Rshare::resetLanguageAndStyle() // Language depended stylesheet // _.lqss -void Rshare::loadStyleSheet(const QString &sheetName) +void RsApplication::loadStyleSheet(const QString &sheetName) { QString locale = QLocale().name(); QString styleSheet; @@ -785,7 +779,7 @@ void Rshare::loadStyleSheet(const QString &sheetName) } /** get list of available stylesheets **/ -void Rshare::getAvailableStyleSheets(QMap &styleSheets) +void RsApplication::getAvailableStyleSheets(QMap &styleSheets) { QFileInfoList fileInfoList = QDir(":/qss/stylesheet/").entryInfoList(QStringList("*.qss")); QFileInfo fileInfo; @@ -813,7 +807,7 @@ void Rshare::getAvailableStyleSheets(QMap &styleSheets) } } -void Rshare::refreshStyleSheet(QWidget *widget, bool processChildren) +void RsApplication::refreshStyleSheet(QWidget *widget, bool processChildren) { if (widget != NULL) { // force widget to recalculate valid style @@ -839,40 +833,35 @@ void Rshare::refreshStyleSheet(QWidget *widget, bool processChildren) } /** Initialize plugins. */ -void Rshare::initPlugins() +void RsApplication::initPlugins() { - loadStyleSheet(_stylesheet); - LanguageSupport::translatePlugins(_language); + loadStyleSheet(options.guiStyleSheetFile); + LanguageSupport::translatePlugins(options.language); } /** Returns the directory RetroShare uses for its data files. */ -QString -Rshare::dataDirectory() +QString RsApplication::dataDirectory() { - if (useConfigDir) - { - return configDir; - } - else if (_args.contains(ARG_DATADIR)) { - return _args.value(ARG_DATADIR); - } - return defaultDataDirectory(); + if(!options.optBaseDir.empty()) + return QString::fromUtf8(options.optBaseDir.c_str()); + else + return defaultDataDirectory(); } /** Returns the default location of RetroShare's data directory. */ QString -Rshare::defaultDataDirectory() +RsApplication::defaultDataDirectory() { #if defined(Q_OS_WIN) return (win32_app_data_folder() + "\\RetroShare"); #else - return (QDir::homePath() + "/.RetroShare"); + return (QDir::homePath() + "/.retroshare"); #endif } -/** Creates Rshare's data directory, if it doesn't already exist. */ +/** Creates RsApplication's data directory, if it doesn't already exist. */ bool -Rshare::createDataDirectory(QString *errmsg) +RsApplication::createDataDirectory(QString *errmsg) { QDir datadir(dataDirectory()); if (!datadir.exists()) { @@ -885,33 +874,29 @@ Rshare::createDataDirectory(QString *errmsg) return true; } -/** Set Rshare's data directory - externally */ -bool Rshare::setConfigDirectory(const QString& dir) +/** Set RsApplication's data directory - externally */ +bool RsApplication::setConfigDirectory(const QString& dir) { - useConfigDir = true; - configDir = dir; + options.optBaseDir = std::string(dir.toUtf8()); return true; } /** Writes msg with severity level to RetroShare's log. */ -Log::LogMessage -Rshare::log(Log::LogLevel level, QString msg) +Log::LogMessage RsApplication::log(Log::LogLevel level, QString msg) { - return _log.log(level, msg); + return log_output.log(level, msg); } /** Creates and binds a shortcut such that when key is pressed in * sender's context, receiver's slot will be called. */ -void -Rshare::createShortcut(const QKeySequence &key, QWidget *sender, - QWidget *receiver, const char *slot) +void RsApplication::createShortcut(const QKeySequence &key, QWidget *sender, QWidget *receiver, const char *slot) { QShortcut *s = new QShortcut(key, sender); connect(s, SIGNAL(activated()), receiver, slot); } #ifdef __APPLE__ -bool Rshare::event(QEvent *event) +bool RsApplication::event(QEvent *event) { switch (event->type()) { case QEvent::FileOpen:{ @@ -933,7 +918,7 @@ bool Rshare::event(QEvent *event) } #endif -void Rshare::blinkTimer() +void RsApplication::blinkTimer() { mBlink = !mBlink; emit blink(mBlink); @@ -944,7 +929,7 @@ void Rshare::blinkTimer() } } -bool Rshare::loadCertificate(const RsPeerId &accountId, bool autoLogin) +bool RsApplication::loadCertificate(const RsPeerId &accountId, bool autoLogin) { if (!RsAccounts::SelectAccount(accountId)) { @@ -985,14 +970,14 @@ bool Rshare::loadCertificate(const RsPeerId &accountId, bool autoLogin) // QObject::tr("Login Failure"), // QObject::tr("Maybe password is wrong") ); return false; - default: std::cerr << "Rshare::loadCertificate() unexpected switch value " << retVal << std::endl; + default: std::cerr << "RsApplication::loadCertificate() unexpected switch value " << retVal << std::endl; return false; } return true; } -bool Rshare::updateLocalServer() +bool RsApplication::updateLocalServer() { if (localServer) { QString serverName = QString(TARGET); diff --git a/retroshare-gui/src/rshare.h b/retroshare-gui/src/rshare.h index 2b59b7875..92b8cdf09 100644 --- a/retroshare-gui/src/rshare.h +++ b/retroshare-gui/src/rshare.h @@ -36,9 +36,10 @@ #include "util/log.h" #include "retroshare/rstypes.h" +#include "retroshare/rsinit.h" /** Pointer to this RetroShare application instance. */ -#define rApp (static_cast(qApp)) +#define rApp (static_cast(qApp)) #define rDebug(fmt) (rApp->log(Log::Debug, (fmt))) #define rInfo(fmt) (rApp->log(Log::Info, (fmt))) @@ -46,20 +47,39 @@ #define rWarn(fmt) (rApp->log(Log::Warn, (fmt))) #define rError(fmt) (rApp->log(Log::Error, (fmt))) +struct RsGUIConfigOptions: public RsConfigOptions +{ + RsGUIConfigOptions() + : logLevel("Off"), argc(0) + {} -class Rshare : public QApplication + QString dateformat; // The format for dates in feed items etc. + QString language; // The current language. + + QString logFileName; // output filename for log + QString logLevel; // severity threshold for log output + + QString guiStyle; // CSS Style for the GUI + QString guiStyleSheetFile; // CSS Style for the GUI + + int argc ; // stores argc parameter. Only used by the creator of QApplication + char *argv[1] ; // stores argv parameter. Only used by the creator of QApplication +}; + +class RsApplication : public QApplication { Q_OBJECT public: /** Constructor. */ - Rshare(QStringList args, int &argc, char **argv, const QString &dir); + RsApplication(const RsGUIConfigOptions& conf); /** Destructor. */ - ~Rshare(); + ~RsApplication(); /** Return the version info */ static QString retroshareVersion(bool=true); +#ifdef TO_REMOVE /** Return the map of command-line arguments and values. */ static QMap arguments() { return _args; } /** Parse the list of command-line arguments. */ @@ -72,6 +92,7 @@ public: static void showUsageMessageBox(); /** Returns true if the user wants to see usage information. */ static bool showUsage(); +#endif /** Sets the current language. */ static bool setLanguage(QString languageCode = QString()); @@ -105,17 +126,22 @@ public: static void initPlugins(); /** Returns the current GUI style. */ - static QString style() { return _style; } + static QString style() { return options.guiStyle; } /** Returns the current GUI stylesheet. */ - static QString stylesheet() { return _stylesheet; } + static QString stylesheet() { return options.guiStyleSheetFile; } /** Returns the current language. */ - static QString language() { return _language; } - /** Returns the operating mode. */ - static QString opmode() { return _opmode; } + static QString language() { return options.language; } + + /** Sets/Returns the operating mode. */ + static void setOpMode(const QString& op ) { options.opModeStr = op.toStdString(); } + static QString opmode() { return QString::fromStdString(options.opModeStr); } + +#ifdef TO_REMOVE /** Returns links passed by arguments. */ static QStringList* links() { return &_links; } /** Returns files passed by arguments. */ static QStringList* files() {return &_files; } +#endif /** Returns Rshare's application startup time. */ static QDateTime startupTime(); @@ -176,24 +202,17 @@ private: /** customize the date format (defaultlongformat) */ static void customizeDateFormat(); +#ifdef TO_REMOVE /** Returns true if the specified arguments wants a value. */ static bool argNeedsValue(const QString &argName); +#endif + - static QMap _args; /**< List of command-line arguments. */ - static Log _log; /**< Logs debugging messages to file or stdout. */ - static QString _style; /**< The current GUI style. */ - static QString _stylesheet; /**< The current GUI stylesheet. */ - static QString _language; /**< The current language. */ - static QString _dateformat; /**< The format for dates in feed items etc. */ - static QString _opmode; /**< The operating mode passed by args. */ - static QStringList _links; /**< List of links passed by arguments. */ - static QStringList _files; /**< List of files passed by arguments. */ static QDateTime mStartupTime; // startup time - - static bool useConfigDir; - static QString configDir; bool mBlink; static QLocalServer* localServer; + static RsGUIConfigOptions options; + static Log log_output; }; #endif diff --git a/retroshare-gui/src/util/DateTime.cpp b/retroshare-gui/src/util/DateTime.cpp index b93a4dfe1..658772c5a 100644 --- a/retroshare-gui/src/util/DateTime.cpp +++ b/retroshare-gui/src/util/DateTime.cpp @@ -30,7 +30,7 @@ QString DateTime::formatLongDate(time_t dateValue) QString DateTime::formatLongDate(const QDate &dateValue) { - QString customDateFormat = Rshare::customDateFormat(); + QString customDateFormat = RsApplication::customDateFormat(); if (customDateFormat.isEmpty()) { return dateValue.toString(Qt::ISODate);