<commit_before>
// Backup related functions are placed here to keep vital sections of
// code contained while maintaining clean code.

#include "walletdb.h"
#include "wallet.h"
#include "util.h"

#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>

#include <fstream>
#include <string>

boost::filesystem::path GetBackupPath();

using namespace boost;

boost::filesystem::path GetBackupPath()
{
    filesystem::path defaultDir = GetDataDir() / "walletbackups";
    return GetArg("-backupdir", defaultDir.string());
}

std::string GetBackupFilename(const std::string& basename, const std::string& suffix = "")
{
    time_t biTime;
    struct tm * blTime;
    time (&biTime);
    blTime = localtime(&biTime);
    char boTime[200];
    strftime(boTime, sizeof(boTime), "%Y-%m-%dT%H-%M-%S", blTime);
    std::string sBackupFilename;
    filesystem::path rpath;
    sBackupFilename = basename + "-" + std::string(boTime);
    if (!suffix.empty())
        sBackupFilename = sBackupFilename + "-" + suffix;
    rpath = GetBackupPath() / sBackupFilename;
    return rpath.string();
}

bool BackupConfigFile(const std::string& strDest)
{
    // Check to see if there is a parent_path in strDest to support custom locations by ui - bug fix

    filesystem::path ConfigSource = GetDataDir() / "gridcoinresearch.conf";
    filesystem::path ConfigTarget = strDest;
    filesystem::create_directories(ConfigTarget.parent_path());
    try
    {
        #if BOOST_VERSION >= 104000
            filesystem::copy_file(ConfigSource, ConfigTarget, filesystem::copy_option::overwrite_if_exists);
        #else
            filesystem::copy_file(ConfigSource, ConfigTarget);
        #endif
        LogPrintf("BackupConfigFile: Copied gridcoinresearch.conf to %s\n", ConfigTarget.string());
        return true;
    }
    catch(const filesystem::filesystem_error &e)
    {
        LogPrintf("BackupConfigFile: Error copying gridcoinresearch.conf to %s - %s\n", ConfigTarget.string(), e.what());
        return false;
    }
    return false;
}

bool BackupWallet(const CWallet& wallet, const std::string& strDest)
{
    if (!wallet.fFileBacked)
        return false;
    while (!fShutdown)
    {
        {
            LOCK(bitdb.cs_db);
            if (!bitdb.mapFileUseCount.count(wallet.strWalletFile) || bitdb.mapFileUseCount[wallet.strWalletFile] == 0)
            {
                // Flush log data to the dat file
                bitdb.CloseDb(wallet.strWalletFile);
                bitdb.CheckpointLSN(wallet.strWalletFile);
                LogPrintf("Issuing lsn_reset for backup file portability.");
                bitdb.lsn_reset(wallet.strWalletFile);
                bitdb.mapFileUseCount.erase(wallet.strWalletFile);

                // Copy wallet.dat
                filesystem::path WalletSource = GetDataDir() / wallet.strWalletFile;
                filesystem::path WalletTarget = strDest;
                filesystem::create_directories(WalletTarget.parent_path());
                if (filesystem::is_directory(WalletTarget))
                    WalletTarget /= wallet.strWalletFile;
                try
                {
                    #if BOOST_VERSION >= 104000
                        filesystem::copy_file(WalletSource, WalletTarget, filesystem::copy_option::overwrite_if_exists);
                    #else
                        filesystem::copy_file(WalletSource, WalletTarget);
                    #endif
                    LogPrintf("BackupWallet: Copied wallet.dat to %s\n", WalletTarget.string());
                    return true;
                }
                catch(const filesystem::filesystem_error &e) {
                    LogPrintf("BackupWallet: Error copying wallet.dat to %s - %s\n", WalletTarget.string(), e.what());
                    return false;
                }
            }
        }
        MilliSleep(100);
    }
    return false;
}

bool BackupPrivateKeys(const CWallet& wallet, std::string& sTarget, std::string& sErrors)
{
    if (wallet.IsLocked() || fWalletUnlockStakingOnly)
    {
        sErrors = "Wallet needs to be fully unlocked to backup private keys.";
        return false;
    }
    filesystem::path PrivateKeysTarget = GetBackupFilename("keys.dat");
    filesystem::create_directories(PrivateKeysTarget.parent_path());
    sTarget = PrivateKeysTarget.string();
    std::ofstream myBackup;
    myBackup.open (PrivateKeysTarget.string().c_str());
    std::string sError;
    for(const auto& keyPair : wallet.GetAllPrivateKeys(sError))
    {
        if (!sError.empty())
        {
            sErrors = sError;
            return false;
        }
        myBackup << "Address: " << keyPair.first.ToString() << ", Secret: " << keyPair.second.ToString() << std::endl;
    }
    LogPrintf("BackupPrivateKeys: Backup made to %s\n", PrivateKeysTarget.string());
    myBackup.close();
    return true;
}
<commit_msg>No need to backup in a loop.<commit_after>
// Backup related functions are placed here to keep vital sections of
// code contained while maintaining clean code.

#include "walletdb.h"
#include "wallet.h"
#include "util.h"

#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>

#include <fstream>
#include <string>

boost::filesystem::path GetBackupPath();

using namespace boost;

boost::filesystem::path GetBackupPath()
{
    filesystem::path defaultDir = GetDataDir() / "walletbackups";
    return GetArg("-backupdir", defaultDir.string());
}

std::string GetBackupFilename(const std::string& basename, const std::string& suffix = "")
{
    time_t biTime;
    struct tm * blTime;
    time (&biTime);
    blTime = localtime(&biTime);
    char boTime[200];
    strftime(boTime, sizeof(boTime), "%Y-%m-%dT%H-%M-%S", blTime);
    std::string sBackupFilename;
    filesystem::path rpath;
    sBackupFilename = basename + "-" + std::string(boTime);
    if (!suffix.empty())
        sBackupFilename = sBackupFilename + "-" + suffix;
    rpath = GetBackupPath() / sBackupFilename;
    return rpath.string();
}

bool BackupConfigFile(const std::string& strDest)
{
    // Check to see if there is a parent_path in strDest to support custom locations by ui - bug fix

    filesystem::path ConfigSource = GetDataDir() / "gridcoinresearch.conf";
    filesystem::path ConfigTarget = strDest;
    filesystem::create_directories(ConfigTarget.parent_path());
    try
    {
        #if BOOST_VERSION >= 104000
            filesystem::copy_file(ConfigSource, ConfigTarget, filesystem::copy_option::overwrite_if_exists);
        #else
            filesystem::copy_file(ConfigSource, ConfigTarget);
        #endif
        LogPrintf("BackupConfigFile: Copied gridcoinresearch.conf to %s\n", ConfigTarget.string());
        return true;
    }
    catch(const filesystem::filesystem_error &e)
    {
        LogPrintf("BackupConfigFile: Error copying gridcoinresearch.conf to %s - %s\n", ConfigTarget.string(), e.what());
        return false;
    }
    return false;
}

bool BackupWallet(const CWallet& wallet, const std::string& strDest)
{
    if (!wallet.fFileBacked)
        return false;

    LOCK(bitdb.cs_db);
    if (!bitdb.mapFileUseCount.count(wallet.strWalletFile) || bitdb.mapFileUseCount[wallet.strWalletFile] == 0)
    {
        // Flush log data to the dat file
        bitdb.CloseDb(wallet.strWalletFile);
        bitdb.CheckpointLSN(wallet.strWalletFile);
        LogPrintf("Issuing lsn_reset for backup file portability.");
        bitdb.lsn_reset(wallet.strWalletFile);
        bitdb.mapFileUseCount.erase(wallet.strWalletFile);

        // Copy wallet.dat
        filesystem::path WalletSource = GetDataDir() / wallet.strWalletFile;
        filesystem::path WalletTarget = strDest;
        filesystem::create_directories(WalletTarget.parent_path());
        if (filesystem::is_directory(WalletTarget))
            WalletTarget /= wallet.strWalletFile;
        try
        {
#if BOOST_VERSION >= 104000
            filesystem::copy_file(WalletSource, WalletTarget, filesystem::copy_option::overwrite_if_exists);
#else
            filesystem::copy_file(WalletSource, WalletTarget);
#endif
            LogPrintf("BackupWallet: Copied wallet.dat to %s\n", WalletTarget.string());
            return true;
        }
        catch(const filesystem::filesystem_error &e) {
            LogPrintf("BackupWallet: Error copying wallet.dat to %s - %s\n", WalletTarget.string(), e.what());
            return false;
        }
    }

    return false;
}

bool BackupPrivateKeys(const CWallet& wallet, std::string& sTarget, std::string& sErrors)
{
    if (wallet.IsLocked() || fWalletUnlockStakingOnly)
    {
        sErrors = "Wallet needs to be fully unlocked to backup private keys.";
        return false;
    }
    filesystem::path PrivateKeysTarget = GetBackupFilename("keys.dat");
    filesystem::create_directories(PrivateKeysTarget.parent_path());
    sTarget = PrivateKeysTarget.string();
    std::ofstream myBackup;
    myBackup.open (PrivateKeysTarget.string().c_str());
    std::string sError;
    for(const auto& keyPair : wallet.GetAllPrivateKeys(sError))
    {
        if (!sError.empty())
        {
            sErrors = sError;
            return false;
        }
        myBackup << "Address: " << keyPair.first.ToString() << ", Secret: " << keyPair.second.ToString() << std::endl;
    }
    LogPrintf("BackupPrivateKeys: Backup made to %s\n", PrivateKeysTarget.string());
    myBackup.close();
    return true;
}
<|endoftext|>


<commit_before>/// @file hdm_serialize_action.cpp
/// @brief Implementation of hdm save & load functions called by clients
/// @author uentity
/// @version
/// @date 30.01.2012
/// @copyright This source code is released under the terms of
///            the BSD License. See LICENSE for more details.

#include "bs_bos_core_data_storage_stdafx.h"

#include "hdm_serialize.h"
#include <fstream>
#include <sstream>

// save to and load from text archives
#include <boost/archive/polymorphic_text_iarchive.hpp>
#include <boost/archive/polymorphic_text_oarchive.hpp>
#include <boost/python.hpp>

// path separator
#ifdef UNIX
#define PATHSEP '/'
#else
#define PATHSEP '\\'
#endif

// extension of file with hdm dump
#define HDM_DUMP_EXT ".hdm"

namespace boarch = boost::archive;
namespace boser = boost::serialization;
namespace bp = boost::python;

namespace blue_sky {

namespace  {

template< class dst_stream >
dst_stream& hdm_serialize_save_impl(
	dst_stream& f,
	smart_ptr< hdm > t,
	const std::string& prj_path,
	const std::string& prj_name,
	const std::string& deep_copy_suffix
){
	// save project path for serialization code
	kernel::idx_dt_ptr p_dt = BS_KERNEL.pert_idx_dt(hdm::bs_type());
	//std::string well_pool_filename = prj_name + "_well_pool.db";
	p_dt->insert< std::string >(prj_path);
	// and project name
	p_dt->insert< std::string >(prj_name);
	// DEBUG
	BSERR << "hdm_serialie_save invoked with" << bs_end;
	BSERR << "project path: " << prj_path << bs_end;
	BSERR << "model path: " << prj_name << bs_end;
	// inform to explicitly copy storage files
	if(deep_copy_suffix.size()) {
		p_dt->insert< std::string >(deep_copy_suffix);
		BSERR << "!model name suffix!: " << deep_copy_suffix << bs_end;
	}

	// make archive
	boarch::polymorphic_text_oarchive oa(f);
	oa << t;

	// clear kernel table to not confuse with further saves
	p_dt->clear< std::string >();
	return f;
}

template< class src_stream >
smart_ptr< hdm > hdm_serialize_load_impl(
	src_stream& f,
	const std::string& prj_path,
	const std::string& prj_name
){
	// save project path for serialization code
	kernel::idx_dt_ptr p_dt = BS_KERNEL.pert_idx_dt(hdm::bs_type());
	//std::string well_pool_filename = prj_name + "_well_pool.db";
	p_dt->insert< std::string >(prj_path);
	// and project name
	p_dt->insert< std::string >(prj_name);

	// load archive
	boarch::polymorphic_text_iarchive ia(f);
	smart_ptr< hdm > t;
	ia >> t;

	// clear kernel table
	p_dt->clear< std::string >();
	// clear dangling refs of loaded in kernel
	BS_KERNEL.tree_gc();

	return t;
}

} /* hidden namespace */

/*-----------------------------------------------------------------
 * save hdm
 *----------------------------------------------------------------*/
void hdm_serialize_save(
	smart_ptr< hdm > t,
	const std::string& prj_path,
	const std::string& prj_name,
	const std::string& deep_copy_suffix
){
	std::string fname = prj_path + PATHSEP + prj_name + HDM_DUMP_EXT;
	std::ofstream f(fname.c_str());
	hdm_serialize_save_impl(f, t, prj_path, prj_name, deep_copy_suffix);
}

std::string hdm_serialize_to_str(
	smart_ptr< hdm > t,
	const std::string& prj_path,
	const std::string& prj_name,
	const std::string& deep_copy_suffix
){
	std::ostringstream f;
	return hdm_serialize_save_impl(f, t, prj_path, prj_name, deep_copy_suffix).str();
}

/*-----------------------------------------------------------------
 * load hdm
 *----------------------------------------------------------------*/
smart_ptr< hdm > hdm_serialize_load(
	const std::string& prj_path,
	const std::string& prj_name
){
	std::ifstream f((prj_path + PATHSEP + prj_name + HDM_DUMP_EXT).c_str());
	return hdm_serialize_load_impl(f, prj_path, prj_name);
}

smart_ptr< hdm > hdm_serialize_from_str(
	const std::string& hdm_dump,
	const std::string& prj_path,
	const std::string& prj_name
){
	std::istringstream f(hdm_dump);
	return hdm_serialize_load_impl(f, prj_path, prj_name);
}

/*-----------------------------------------------------------------
 * export save & load to python
 *----------------------------------------------------------------*/
BOOST_PYTHON_FUNCTION_OVERLOADS(hdm_serialize_save_overl, hdm_serialize_save, 3, 4)
//BOOST_PYTHON_FUNCTION_OVERLOADS(hdm_serialize_load_overl, hdm_serialize_load, 2, 3)
BOOST_PYTHON_FUNCTION_OVERLOADS(hdm_serialize_to_str_overl, hdm_serialize_to_str, 3, 4)
//BOOST_PYTHON_FUNCTION_OVERLOADS(hdm_serialize_from_str_overl, hdm_serialize_from_str, 3, 4)

namespace python {

BS_API_PLUGIN void py_export_hdm_serialize() {
	bp::def("hdm_serialize_save", &hdm_serialize_save, hdm_serialize_save_overl());
	bp::def("hdm_serialize_load", &hdm_serialize_load);
    // register pvt to/from str serialization
	bp::def("serialize_to_str", &blue_sky::hdm_serialize_to_str, hdm_serialize_to_str_overl());
	bp::def("serialize_from_str", &blue_sky::hdm_serialize_from_str);
}

} /* python */

} /* blue_sky */
<commit_msg>SRZ: add exception safety to hdm serialization<commit_after>/// @file hdm_serialize_action.cpp
/// @brief Implementation of hdm save & load functions called by clients
/// @author uentity
/// @version
/// @date 30.01.2012
/// @copyright This source code is released under the terms of
///            the BSD License. See LICENSE for more details.

#include "bs_bos_core_data_storage_stdafx.h"

#include "hdm_serialize.h"
#include <fstream>
#include <sstream>

// save to and load from text archives
#include <boost/archive/polymorphic_text_iarchive.hpp>
#include <boost/archive/polymorphic_text_oarchive.hpp>
#include <boost/python.hpp>

// path separator
#ifdef UNIX
#define PATHSEP '/'
#else
#define PATHSEP '\\'
#endif

// extension of file with hdm dump
#define HDM_DUMP_EXT ".hdm"

namespace boarch = boost::archive;
namespace boser = boost::serialization;
namespace bp = boost::python;

namespace blue_sky {

namespace  {

template< class dst_stream >
dst_stream& hdm_serialize_save_impl(
	dst_stream& f,
	smart_ptr< hdm > t,
	const std::string& prj_path,
	const std::string& prj_name,
	const std::string& deep_copy_suffix
){
	// save project path for serialization code
	kernel::idx_dt_ptr p_dt = BS_KERNEL.pert_idx_dt(hdm::bs_type());
	//std::string well_pool_filename = prj_name + "_well_pool.db";
	p_dt->insert< std::string >(prj_path);
	// and project name
	p_dt->insert< std::string >(prj_name);
	// DEBUG
	//BSERR << "hdm_serialize_save invoked with" << bs_end;
	//BSERR << "project path: " << prj_path << bs_end;
	//BSERR << "model path: " << prj_name << bs_end;
	// inform to explicitly copy storage files
	if(deep_copy_suffix.size()) {
		p_dt->insert< std::string >(deep_copy_suffix);
		//BSERR << "!model name suffix!: " << deep_copy_suffix << bs_end;
	}

	// make archive
	try {
		boarch::polymorphic_text_oarchive oa(f);
		oa << t;
	}
	catch(const bs_exception& e) {
		BSERR << std::string("Error during hdm_serialize_save: ") + e.what() << bs_end;
	}
	catch(const std::exception& e) {
		BSERR << std::string("Error during hdm_serialize_save: ") + e.what() << bs_end;
	}
	catch(...) {
		BSERR << "Unknown error during hdm_serialize_save!" << bs_end;
		// clear kernel table to not confuse with further saves
		p_dt->clear< std::string >();
		throw;
	}

	// clear kernel table to not confuse with further saves
	p_dt->clear< std::string >();
	return f;
}

template< class src_stream >
smart_ptr< hdm > hdm_serialize_load_impl(
	src_stream& f,
	const std::string& prj_path,
	const std::string& prj_name
){
	// save project path for serialization code
	kernel::idx_dt_ptr p_dt = BS_KERNEL.pert_idx_dt(hdm::bs_type());
	//std::string well_pool_filename = prj_name + "_well_pool.db";
	p_dt->insert< std::string >(prj_path);
	// and project name
	p_dt->insert< std::string >(prj_name);

	// load archive
	// actually need to rethrow all exceptions
	smart_ptr< hdm > t;
	try {
		boarch::polymorphic_text_iarchive ia(f);
		ia >> t;
	}
	catch(const bs_exception& e) {
		BSERR << std::string("Error during hdm_serialize_load: ") + e.what() << bs_end;
		// clear kernel table
		p_dt->clear< std::string >();
		throw;
		//t = BS_KERNEL.create_object(hdm::bs_type());
		//t.release();
	}
	catch(const std::exception& e) {
		BSERR << std::string("Error during hdm_serialize_load: ") + e.what() << bs_end;
		// clear kernel table
		p_dt->clear< std::string >();
		throw;
		//t = BS_KERNEL.create_object(hdm::bs_type());
		//t.release();
	}
	catch(...) {
		BSERR << "Unknown error during hdm_serialize_save!" << bs_end;
		// clear kernel table
		p_dt->clear< std::string >();
		throw;
	}

	// clear kernel table
	p_dt->clear< std::string >();
	// clear dangling refs of loaded in kernel
	//BS_KERNEL.tree_gc();

	return t;
}

} /* hidden namespace */

/*-----------------------------------------------------------------
 * save hdm
 *----------------------------------------------------------------*/
void hdm_serialize_save(
	smart_ptr< hdm > t,
	const std::string& prj_path,
	const std::string& prj_name,
	const std::string& deep_copy_suffix
){
	std::string fname = prj_path + PATHSEP + prj_name + HDM_DUMP_EXT;
	std::ofstream f(fname.c_str());
	hdm_serialize_save_impl(f, t, prj_path, prj_name, deep_copy_suffix);
}

std::string hdm_serialize_to_str(
	smart_ptr< hdm > t,
	const std::string& prj_path,
	const std::string& prj_name,
	const std::string& deep_copy_suffix
){
	std::ostringstream f;
	return hdm_serialize_save_impl(f, t, prj_path, prj_name, deep_copy_suffix).str();
}

/*-----------------------------------------------------------------
 * load hdm
 *----------------------------------------------------------------*/
smart_ptr< hdm > hdm_serialize_load(
	const std::string& prj_path,
	const std::string& prj_name
){
	std::ifstream f((prj_path + PATHSEP + prj_name + HDM_DUMP_EXT).c_str());
	return hdm_serialize_load_impl(f, prj_path, prj_name);
}

smart_ptr< hdm > hdm_serialize_from_str(
	const std::string& hdm_dump,
	const std::string& prj_path,
	const std::string& prj_name
){
	std::istringstream f(hdm_dump);
	return hdm_serialize_load_impl(f, prj_path, prj_name);
}

/*-----------------------------------------------------------------
 * export save & load to python
 *----------------------------------------------------------------*/
BOOST_PYTHON_FUNCTION_OVERLOADS(hdm_serialize_save_overl, hdm_serialize_save, 3, 4)
//BOOST_PYTHON_FUNCTION_OVERLOADS(hdm_serialize_load_overl, hdm_serialize_load, 2, 3)
BOOST_PYTHON_FUNCTION_OVERLOADS(hdm_serialize_to_str_overl, hdm_serialize_to_str, 3, 4)
//BOOST_PYTHON_FUNCTION_OVERLOADS(hdm_serialize_from_str_overl, hdm_serialize_from_str, 3, 4)

namespace python {

BS_API_PLUGIN void py_export_hdm_serialize() {
	bp::def("hdm_serialize_save", &hdm_serialize_save, hdm_serialize_save_overl());
	bp::def("hdm_serialize_load", &hdm_serialize_load);
    // register pvt to/from str serialization
	bp::def("serialize_to_str", &blue_sky::hdm_serialize_to_str, hdm_serialize_to_str_overl());
	bp::def("serialize_from_str", &blue_sky::hdm_serialize_from_str);
}

} /* python */

} /* blue_sky */
<|endoftext|>


<commit_before><commit_msg>POSIX: sanitise signal handling state at startup.<commit_after><|endoftext|>


<commit_before>#include "MainDialog.h"
#include <QDir>
#include <QDebug>
#include <QMenu>
#include <QProcess>
#include <QMessageBox>
#include <QApplication>
#include <QCoreApplication>
#include <QFileIconProvider>
#include <QDesktopServices>

#ifdef WIN32
#include <Windows.h>
#include <tchar.h>
#endif

int const MainDialog::EXIT_CODE_REBOOT = -123456789;

MainDialog::MainDialog(QWidget *parent) :
    QDialog(parent)
{
    initUI();
    initConnect();
}

MainDialog::~MainDialog()
{
}

void MainDialog::onActionTrigger(bool checked)
{
    Q_UNUSED(checked)
    QAction* action = qobject_cast<QAction*>(sender());
    if(!action) return;
    SExecItem item = m_actionHash.value(action);
    if(item.executableFilename.isEmpty()) return;

    //QFileInfo info(item.executableFilename);
    //QProcess::startDetached(item.batFilename, QStringList(),info.path());

    processItem(item);
}

void MainDialog::processItem(const SExecItem &item)
{
    if(!QFile::exists(item.executableFilename))
    {
        QMessageBox::critical(this, tr("Error"), tr("File Lost : %1").arg(item.executableFilename));
        return;
    }
#ifdef WIN32
    DWORD nShow = item.hide ? SW_HIDE : SW_SHOW;
    ::ShellExecute(NULL, NULL, item.executableFilename.toStdWString().c_str(), NULL, NULL, nShow);
#endif

    if(m_retryMode)
    {
        m_lastItem = item;

        //change icon
        QIcon icon = getFileLogo(m_lastItem.executableFilename);
        if(icon.isNull())
        {
            icon = m_defaultRetryIcon;
        }
        m_trayIcon->setIcon(icon);
        updateTooltip();
    }
}

void MainDialog::updateTooltip()
{
    QString tooltip;
    if(!m_lastItem.executableFilename.isEmpty() && m_retryMode)
    {
        tooltip = tr("LeftClick: ") + QFileInfo(m_lastItem.executableFilename).completeBaseName() + "\n" +
                tr("MidClick: Clear LeftClick") + "\n" +
                tr("RightClick: Open Menu");
    }
    else
    {
        tooltip = tr("RightClick: Open Menu");
    }
    m_trayIcon->setToolTip(tooltip);
}

void MainDialog::clearRetryMode()
{
    m_lastItem.executableFilename.clear();
    updateTooltip();
    m_trayIcon->setIcon(m_logo);
}

void MainDialog::onOpenConfigFolder(bool checked)
{
    Q_UNUSED(checked)
    QString path = QApplication::applicationDirPath() + "/config";
    QDesktopServices::openUrl(QUrl("file:///" + path, QUrl::TolerantMode));
}

void MainDialog::onProjectPage(bool checked)
{
    Q_UNUSED(checked)
    QDesktopServices::openUrl(QUrl("https://github.com/guoming0000/BatchRunTrayTool"));
}

void MainDialog::onFeedback(bool checked)
{
    Q_UNUSED(checked)
    QDesktopServices::openUrl(QUrl("https://github.com/guoming0000/BatchRunTrayTool/issues"));
}

void MainDialog::onUsage(bool checked)
{
    Q_UNUSED(checked)
    QDesktopServices::openUrl(QUrl("https://github.com/guoming0000/BatchRunTrayTool/blob/master/README.md"));
}

void MainDialog::onAutoStart(bool checked)
{
    QString application_name = QApplication::applicationName();
    QSettings *settings = new QSettings("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat);
    if(checked)
    {
        QString application_path = QDir::toNativeSeparators(QApplication::applicationFilePath());
        settings->setValue(application_name, application_path);
    }
    else
    {
        settings->remove(application_name);
    }
    delete settings;
}

void MainDialog::onSetRetryMode(bool checked)
{
    QSettings settings(QSettings::IniFormat, QSettings::UserScope, "BrightGuo", QApplication::applicationName());
    if(checked)
    {
        settings.setValue("UseRetry", true);
        m_retryMode = true;
    }
    else
    {
        settings.setValue("UseRetry", false);
        m_retryMode = false;
        clearRetryMode();
    }
}

void MainDialog::onReloadConfig(bool checked)
{
    Q_UNUSED(checked)
    qApp->exit(MainDialog::EXIT_CODE_REBOOT);
}

void MainDialog::onActivated(QSystemTrayIcon::ActivationReason reason)
{
    switch(reason)
    {
        case QSystemTrayIcon::Context://right click
        {
            m_trayIcon->contextMenu()->popup(QCursor::pos());
            break;
        }
        case QSystemTrayIcon::Trigger://left click
        {
            if(!m_lastItem.executableFilename.isEmpty() && m_retryMode)
            {
                processItem(m_lastItem);
            }
            break;
        }
        case QSystemTrayIcon::MiddleClick:
        {
            if(m_retryMode)
            {
                clearRetryMode();
            }
            break;
        }
    }
}

void MainDialog::initUI()
{
    m_retryMode = false;
    m_trayIconMenu = new QMenu(this);
    //QFont font = m_trayIconMenu->font();
    //font.setPointSize(font.pointSize() * 1.5);
    //m_trayIconMenu->setFont(font);
    QStringList outFolderList = listAllDirs(QApplication::applicationDirPath() + "/config");
    for(int i = 0; i < outFolderList.count(); ++i)
    {
        QString firstDirs = outFolderList.at(i);
        QMenu* firstMenu = 0;
        QFileInfo fi(firstDirs);
        if(firstDirs.contains(PROPERTY_SEPARATOR))
        {
            m_trayIconMenu->addSeparator();
        }
        else if(!isPropertyFile(firstDirs) && fi.isFile())
        {
            createActionWithFolder(m_trayIconMenu, firstDirs);
        }
        else if(fi.isDir())
        {
            firstMenu = createMenu(firstDirs);
        }
        if(firstMenu)
        {
            m_trayIconMenu->addMenu(firstMenu);
        }
    }

    //add exit action
    QMenu *aboutMenu = new QMenu(tr("About") ,this);
    aboutMenu->setIcon(QIcon(":/photo/about.png"));

    QAction *openConfig = new QAction(tr("Open Config Folder"));
    openConfig->setIcon(QIcon(":/photo/folder.png"));
    connect(openConfig, &QAction::triggered, this, &MainDialog::onOpenConfigFolder);
    aboutMenu->addAction(openConfig);

    QAction *reloadConfig = new QAction(tr("Reload Config"));
    reloadConfig->setIcon(QIcon(":/photo/reload_config.png"));
    connect(reloadConfig, &QAction::triggered, this, &MainDialog::onReloadConfig);
    aboutMenu->addAction(reloadConfig);

    QAction *projectPageAction = new QAction(tr("Project Page"));
    projectPageAction->setIcon(QIcon(":/photo/project_page.png"));
    connect(projectPageAction, &QAction::triggered, this, &MainDialog::onProjectPage);
    aboutMenu->addAction(projectPageAction);

    QAction *feedbackAction = new QAction(tr("Feedback"));
    feedbackAction->setIcon(QIcon(":/photo/feedback.png"));
    connect(feedbackAction, &QAction::triggered, this, &MainDialog::onFeedback);
    aboutMenu->addAction(feedbackAction);

    QAction *usageAction = new QAction(tr("Usage"));
    usageAction->setIcon(QIcon(":/photo/usage.png"));
    connect(usageAction, &QAction::triggered, this, &MainDialog::onUsage);
    aboutMenu->addAction(usageAction);

    m_autoStart = new QAction(tr("AutoStart"));
    m_autoStart->setCheckable(true);
    connect(m_autoStart, &QAction::triggered, this, &MainDialog::onAutoStart);
    aboutMenu->addAction(m_autoStart);
    initAutoStartAction();

    m_retryAction = new QAction(tr("Retry Mode"));
    m_retryAction->setCheckable(true);
    connect(m_retryAction, &QAction::triggered, this, &MainDialog::onSetRetryMode);
    aboutMenu->addAction(m_retryAction);
    initRetryAction();

    QAction *exitAction = new QAction(tr("Exit"));
    exitAction->setIcon(QIcon(":/photo/exit.png"));
    connect(exitAction, &QAction::triggered, this, &QCoreApplication::quit);
    aboutMenu->addAction(exitAction);
    m_trayIconMenu->addMenu(aboutMenu);

    m_trayIcon = new QSystemTrayIcon(this);
    m_trayIcon->setContextMenu(m_trayIconMenu);
    m_logo =  QIcon(":/photo/logo.png");
    m_trayIcon->setIcon(m_logo);

    connect(m_trayIcon, &QSystemTrayIcon::activated, this, &MainDialog::onActivated);

    setWindowIcon(m_logo);
    m_trayIcon->show();

    m_defaultRetryIcon = QIcon(":/photo/retry.png");
    updateTooltip();
}

void MainDialog::initConnect()
{

}

QString MainDialog::findFilePath(const QString &path)
{
    QDir dir(path);
    QStringList list = dir.entryList(QDir::Files);

    if(list.count() > 0)
    {
        return dir.absoluteFilePath(list.at(0));
    }
    else
    {
        return QString();
    }
}

QStringList MainDialog::listAllDirs(const QString &path)
{
    QDir dir(path);
    QStringList list;
    QStringList dirs = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Files);
    for(int i = 0; i < dirs.count(); ++i)
    {
        list.push_back(dir.absoluteFilePath(dirs.at(i)));
    }
    return list;
}

QIcon MainDialog::getPathLogo(const QString &path)
{
    QString logoPath = path + "/" + PROPERTY_LOGO;
    if(QFile::exists(logoPath))
    {
        return QIcon(logoPath);
    }
    else
    {
        return QIcon();
    }
}

QIcon MainDialog::getFileLogo(const QString &filename)
{
    QFileInfo info(filename);
    QIcon icon;
    if(QFile::exists(info.absolutePath() + "/" + info.baseName() + PROPERTY_LOGO))
    {
        icon = QIcon(info.absolutePath() + "/" + info.baseName() + PROPERTY_LOGO);
    }
    else if(QFile::exists(info.absolutePath() + "/" + info.completeBaseName() + PROPERTY_LOGO))
    {
        icon = QIcon(info.absolutePath() + "/" + info.completeBaseName() + PROPERTY_LOGO);
    }
    else if(QFile::exists(info.absolutePath() + "/" + info.fileName() + PROPERTY_LOGO))
    {
        icon = QIcon(info.absolutePath() + "/" + info.fileName() + PROPERTY_LOGO);
    }
    else
    {
        QFileIconProvider provider;
        icon = provider.icon(info);
    }
    return icon;
}

QMenu *MainDialog::createMenu(const QString &path)
{
    QDir sencondFolderDir(path);
    //QString dirName = sencondFolderDir.dirName();
    QMenu *secondMenu = new QMenu(sencondFolderDir.dirName(), this);
    secondMenu->setIcon(getPathLogo(path));
    QStringList folderList = listAllDirs(path);
    for(int i = 0; i < folderList.count(); ++i)
    {
        QString secondDirs = folderList.at(i);
        QDir secondFolderDir(secondDirs);
        QFileInfo fi(secondDirs);
        if(secondDirs.contains(PROPERTY_SEPARATOR))
        {
            secondMenu->addSeparator();
        }
        else
        {
            if(!isPropertyFile(secondDirs) && fi.isFile())
            {
                createActionWithFolder(secondMenu, secondDirs);
            }
            else if(fi.isDir())
            {
                QMenu *thirdMenu = new QMenu(secondFolderDir.dirName(), this);
                QStringList thirdFolderList = listAllDirs(secondDirs);
                for(int i = 0; i < thirdFolderList.count(); ++i)
                {
                    QString thirdDirs = thirdFolderList.at(i);
                    QFileInfo newFi(thirdDirs);
                    if(thirdDirs.contains(PROPERTY_SEPARATOR))
                    {
                        thirdMenu->addSeparator();
                    }
                    else
                    {
                        if(!isPropertyFile(thirdDirs) && newFi.isFile())
                        {
                            createActionWithFolder(thirdMenu, thirdDirs);
                        }
                    }
                }
                if(thirdMenu)
                {
                    thirdMenu->setIcon(getPathLogo(secondDirs));
                    secondMenu->addMenu(thirdMenu);
                }
            }
        }
    }
    return secondMenu;
}

//check if it's a property file
bool MainDialog::isPropertyFile(const QString &dirname)
{
    int count = _countof(PROPERTYS);
    for(int i = 0; i < count; ++i)
    {
        if(dirname.endsWith(PROPERTYS[i]))
        {
            return true;
        }
    }
    return false;
}

QAction* MainDialog::createActionWithFolder(QMenu* menu, const QString &filename)
{
    QAction *action = 0;
    QFileInfo fi(filename);
    if(fi.exists())
    {
        action = new QAction(fi.completeBaseName());
        action->setIcon(getFileLogo(filename));
        connect(action, &QAction::triggered, this, &MainDialog::onActionTrigger);

        SExecItem item;
        item.executableFilename = filename;
        item.hide = true;
        if(QFile::exists(fi.absolutePath() + "/" + fi.fileName() + PROPERTY_SHOW) ||
                QFile::exists(fi.absolutePath() + "/" + fi.baseName() + PROPERTY_SHOW) ||
                QFile::exists(fi.absolutePath() + "/" + fi.completeBaseName() + PROPERTY_SHOW))
        {
            item.hide = false;
        }

        m_actionHash.insert(action, item);
        if(menu)
        {
            menu->addAction(action);
        }
    }

    return action;
}

void MainDialog::initAutoStartAction()
{
    QString application_name = QApplication::applicationName();
    QSettings settings("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat);
    QString application_path = QApplication::applicationFilePath();
    QString regeditPath = QDir::fromNativeSeparators(settings.value(application_name).toString());
    QString realPath = QDir::fromNativeSeparators(application_path);
    if(regeditPath.compare(realPath) == 0)
    {
        m_autoStart->setChecked(true);
    }
    else
    {
        m_autoStart->setChecked(false);
    }
}

void MainDialog::initRetryAction()
{
    QSettings settings(QSettings::IniFormat, QSettings::UserScope, "BrightGuo", QApplication::applicationName());
    if(settings.value("UseRetry").toBool())
    {
        m_retryAction->setChecked(true);
        m_retryMode = true;
    }
    else
    {
        m_retryAction->setChecked(false);
        m_retryMode = false;
    }
}
<commit_msg>试下能否修复右键打开菜单速度慢问题<commit_after>#include "MainDialog.h"
#include <QDir>
#include <QDebug>
#include <QMenu>
#include <QProcess>
#include <QMessageBox>
#include <QApplication>
#include <QCoreApplication>
#include <QFileIconProvider>
#include <QDesktopServices>

#ifdef WIN32
#include <Windows.h>
#include <tchar.h>
#endif

int const MainDialog::EXIT_CODE_REBOOT = -123456789;

MainDialog::MainDialog(QWidget *parent) :
    QDialog(parent)
{
    initUI();
    initConnect();
}

MainDialog::~MainDialog()
{
}

void MainDialog::onActionTrigger(bool checked)
{
    Q_UNUSED(checked)
    QAction* action = qobject_cast<QAction*>(sender());
    if(!action) return;
    SExecItem item = m_actionHash.value(action);
    if(item.executableFilename.isEmpty()) return;

    //QFileInfo info(item.executableFilename);
    //QProcess::startDetached(item.batFilename, QStringList(),info.path());

    processItem(item);
}

void MainDialog::processItem(const SExecItem &item)
{
    if(!QFile::exists(item.executableFilename))
    {
        QMessageBox::critical(this, tr("Error"), tr("File Lost : %1").arg(item.executableFilename));
        return;
    }
#ifdef WIN32
    DWORD nShow = item.hide ? SW_HIDE : SW_SHOW;
    ::ShellExecute(NULL, NULL, item.executableFilename.toStdWString().c_str(), NULL, NULL, nShow);
#endif

    if(m_retryMode)
    {
        m_lastItem = item;

        //change icon
        QIcon icon = getFileLogo(m_lastItem.executableFilename);
        if(icon.isNull())
        {
            icon = m_defaultRetryIcon;
        }
        m_trayIcon->setIcon(icon);
        updateTooltip();
    }
}

void MainDialog::updateTooltip()
{
    QString tooltip;
    if(!m_lastItem.executableFilename.isEmpty() && m_retryMode)
    {
        tooltip = tr("LeftClick: ") + QFileInfo(m_lastItem.executableFilename).completeBaseName() + "\n" +
                tr("MidClick: Clear LeftClick") + "\n" +
                tr("RightClick: Open Menu");
    }
    else
    {
        tooltip = tr("RightClick: Open Menu");
    }
    m_trayIcon->setToolTip(tooltip);
}

void MainDialog::clearRetryMode()
{
    m_lastItem.executableFilename.clear();
    updateTooltip();
    m_trayIcon->setIcon(m_logo);
}

void MainDialog::onOpenConfigFolder(bool checked)
{
    Q_UNUSED(checked)
    QString path = QApplication::applicationDirPath() + "/config";
    QDesktopServices::openUrl(QUrl("file:///" + path, QUrl::TolerantMode));
}

void MainDialog::onProjectPage(bool checked)
{
    Q_UNUSED(checked)
    QDesktopServices::openUrl(QUrl("https://github.com/guoming0000/BatchRunTrayTool"));
}

void MainDialog::onFeedback(bool checked)
{
    Q_UNUSED(checked)
    QDesktopServices::openUrl(QUrl("https://github.com/guoming0000/BatchRunTrayTool/issues"));
}

void MainDialog::onUsage(bool checked)
{
    Q_UNUSED(checked)
    QDesktopServices::openUrl(QUrl("https://github.com/guoming0000/BatchRunTrayTool/blob/master/README.md"));
}

void MainDialog::onAutoStart(bool checked)
{
    QString application_name = QApplication::applicationName();
    QSettings *settings = new QSettings("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat);
    if(checked)
    {
        QString application_path = QDir::toNativeSeparators(QApplication::applicationFilePath());
        settings->setValue(application_name, application_path);
    }
    else
    {
        settings->remove(application_name);
    }
    delete settings;
}

void MainDialog::onSetRetryMode(bool checked)
{
    QSettings settings(QSettings::IniFormat, QSettings::UserScope, "BrightGuo", QApplication::applicationName());
    if(checked)
    {
        settings.setValue("UseRetry", true);
        m_retryMode = true;
    }
    else
    {
        settings.setValue("UseRetry", false);
        m_retryMode = false;
        clearRetryMode();
    }
}

void MainDialog::onReloadConfig(bool checked)
{
    Q_UNUSED(checked)
    qApp->exit(MainDialog::EXIT_CODE_REBOOT);
}

void MainDialog::onActivated(QSystemTrayIcon::ActivationReason reason)
{
    switch(reason)
    {
        case QSystemTrayIcon::Context://right click
        {
            m_trayIcon->contextMenu()->popup(QCursor::pos());
            break;
        }
        case QSystemTrayIcon::Trigger://left click
        {
            if(!m_lastItem.executableFilename.isEmpty() && m_retryMode)
            {
                processItem(m_lastItem);
            }
            break;
        }
        case QSystemTrayIcon::MiddleClick:
        {
            if(m_retryMode)
            {
                clearRetryMode();
            }
            break;
        }
    }
}

void MainDialog::initUI()
{
    m_retryMode = false;
    m_trayIconMenu = new QMenu(this);
    //QFont font = m_trayIconMenu->font();
    //font.setPointSize(font.pointSize() * 1.5);
    //m_trayIconMenu->setFont(font);
    QStringList outFolderList = listAllDirs(QApplication::applicationDirPath() + "/config");
    for(int i = 0; i < outFolderList.count(); ++i)
    {
        QString firstDirs = outFolderList.at(i);
        QMenu* firstMenu = 0;
        QFileInfo fi(firstDirs);
        if(firstDirs.contains(PROPERTY_SEPARATOR))
        {
            m_trayIconMenu->addSeparator();
        }
        else if(!isPropertyFile(firstDirs) && fi.isFile())
        {
            createActionWithFolder(m_trayIconMenu, firstDirs);
        }
        else if(fi.isDir())
        {
            firstMenu = createMenu(firstDirs);
        }
        if(firstMenu)
        {
            m_trayIconMenu->addMenu(firstMenu);
        }
    }

    //add exit action
    QMenu *aboutMenu = new QMenu(tr("About") ,this);
    aboutMenu->setIcon(QIcon(":/photo/about.png"));

    QAction *openConfig = new QAction(tr("Open Config Folder"));
    openConfig->setIcon(QIcon(":/photo/folder.png"));
    connect(openConfig, &QAction::triggered, this, &MainDialog::onOpenConfigFolder);
    aboutMenu->addAction(openConfig);

    QAction *reloadConfig = new QAction(tr("Reload Config"));
    reloadConfig->setIcon(QIcon(":/photo/reload_config.png"));
    connect(reloadConfig, &QAction::triggered, this, &MainDialog::onReloadConfig);
    aboutMenu->addAction(reloadConfig);

    QAction *projectPageAction = new QAction(tr("Project Page"));
    projectPageAction->setIcon(QIcon(":/photo/project_page.png"));
    connect(projectPageAction, &QAction::triggered, this, &MainDialog::onProjectPage);
    aboutMenu->addAction(projectPageAction);

    QAction *feedbackAction = new QAction(tr("Feedback"));
    feedbackAction->setIcon(QIcon(":/photo/feedback.png"));
    connect(feedbackAction, &QAction::triggered, this, &MainDialog::onFeedback);
    aboutMenu->addAction(feedbackAction);

    QAction *usageAction = new QAction(tr("Usage"));
    usageAction->setIcon(QIcon(":/photo/usage.png"));
    connect(usageAction, &QAction::triggered, this, &MainDialog::onUsage);
    aboutMenu->addAction(usageAction);

    m_autoStart = new QAction(tr("AutoStart"));
    m_autoStart->setCheckable(true);
    connect(m_autoStart, &QAction::triggered, this, &MainDialog::onAutoStart);
    aboutMenu->addAction(m_autoStart);
    initAutoStartAction();

    m_retryAction = new QAction(tr("Retry Mode"));
    m_retryAction->setCheckable(true);
    connect(m_retryAction, &QAction::triggered, this, &MainDialog::onSetRetryMode);
    aboutMenu->addAction(m_retryAction);
    initRetryAction();

    QAction *exitAction = new QAction(tr("Exit"));
    exitAction->setIcon(QIcon(":/photo/exit.png"));
    connect(exitAction, &QAction::triggered, this, &QCoreApplication::quit);
    aboutMenu->addAction(exitAction);
    m_trayIconMenu->addMenu(aboutMenu);
    m_trayIconMenu->setContextMenuPolicy(Qt::ActionsContextMenu);

    m_trayIcon = new QSystemTrayIcon(this);
    m_trayIcon->setContextMenu(m_trayIconMenu);
    m_logo =  QIcon(":/photo/logo.png");
    m_trayIcon->setIcon(m_logo);

    connect(m_trayIcon, &QSystemTrayIcon::activated, this, &MainDialog::onActivated);

    setWindowIcon(m_logo);
    m_trayIcon->show();

    m_defaultRetryIcon = QIcon(":/photo/retry.png");
    updateTooltip();
}

void MainDialog::initConnect()
{

}

QString MainDialog::findFilePath(const QString &path)
{
    QDir dir(path);
    QStringList list = dir.entryList(QDir::Files);

    if(list.count() > 0)
    {
        return dir.absoluteFilePath(list.at(0));
    }
    else
    {
        return QString();
    }
}

QStringList MainDialog::listAllDirs(const QString &path)
{
    QDir dir(path);
    QStringList list;
    QStringList dirs = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Files);
    for(int i = 0; i < dirs.count(); ++i)
    {
        list.push_back(dir.absoluteFilePath(dirs.at(i)));
    }
    return list;
}

QIcon MainDialog::getPathLogo(const QString &path)
{
    QString logoPath = path + "/" + PROPERTY_LOGO;
    if(QFile::exists(logoPath))
    {
        return QIcon(logoPath);
    }
    else
    {
        return QIcon();
    }
}

QIcon MainDialog::getFileLogo(const QString &filename)
{
    QFileInfo info(filename);
    QIcon icon;
    if(QFile::exists(info.absolutePath() + "/" + info.baseName() + PROPERTY_LOGO))
    {
        icon = QIcon(info.absolutePath() + "/" + info.baseName() + PROPERTY_LOGO);
    }
    else if(QFile::exists(info.absolutePath() + "/" + info.completeBaseName() + PROPERTY_LOGO))
    {
        icon = QIcon(info.absolutePath() + "/" + info.completeBaseName() + PROPERTY_LOGO);
    }
    else if(QFile::exists(info.absolutePath() + "/" + info.fileName() + PROPERTY_LOGO))
    {
        icon = QIcon(info.absolutePath() + "/" + info.fileName() + PROPERTY_LOGO);
    }
    else
    {
        QFileIconProvider provider;
        icon = provider.icon(info);
    }
    return icon;
}

QMenu *MainDialog::createMenu(const QString &path)
{
    QDir sencondFolderDir(path);
    //QString dirName = sencondFolderDir.dirName();
    QMenu *secondMenu = new QMenu(sencondFolderDir.dirName(), this);
    secondMenu->setIcon(getPathLogo(path));
    QStringList folderList = listAllDirs(path);
    for(int i = 0; i < folderList.count(); ++i)
    {
        QString secondDirs = folderList.at(i);
        QDir secondFolderDir(secondDirs);
        QFileInfo fi(secondDirs);
        if(secondDirs.contains(PROPERTY_SEPARATOR))
        {
            secondMenu->addSeparator();
        }
        else
        {
            if(!isPropertyFile(secondDirs) && fi.isFile())
            {
                createActionWithFolder(secondMenu, secondDirs);
            }
            else if(fi.isDir())
            {
                QMenu *thirdMenu = new QMenu(secondFolderDir.dirName(), this);
                QStringList thirdFolderList = listAllDirs(secondDirs);
                for(int i = 0; i < thirdFolderList.count(); ++i)
                {
                    QString thirdDirs = thirdFolderList.at(i);
                    QFileInfo newFi(thirdDirs);
                    if(thirdDirs.contains(PROPERTY_SEPARATOR))
                    {
                        thirdMenu->addSeparator();
                    }
                    else
                    {
                        if(!isPropertyFile(thirdDirs) && newFi.isFile())
                        {
                            createActionWithFolder(thirdMenu, thirdDirs);
                        }
                    }
                }
                if(thirdMenu)
                {
                    thirdMenu->setIcon(getPathLogo(secondDirs));
                    secondMenu->addMenu(thirdMenu);
                }
            }
        }
    }
    return secondMenu;
}

//check if it's a property file
bool MainDialog::isPropertyFile(const QString &dirname)
{
    int count = _countof(PROPERTYS);
    for(int i = 0; i < count; ++i)
    {
        if(dirname.endsWith(PROPERTYS[i]))
        {
            return true;
        }
    }
    return false;
}

QAction* MainDialog::createActionWithFolder(QMenu* menu, const QString &filename)
{
    QAction *action = 0;
    QFileInfo fi(filename);
    if(fi.exists())
    {
        action = new QAction(fi.completeBaseName());
        action->setIcon(getFileLogo(filename));
        connect(action, &QAction::triggered, this, &MainDialog::onActionTrigger);

        SExecItem item;
        item.executableFilename = filename;
        item.hide = true;
        if(QFile::exists(fi.absolutePath() + "/" + fi.fileName() + PROPERTY_SHOW) ||
                QFile::exists(fi.absolutePath() + "/" + fi.baseName() + PROPERTY_SHOW) ||
                QFile::exists(fi.absolutePath() + "/" + fi.completeBaseName() + PROPERTY_SHOW))
        {
            item.hide = false;
        }

        m_actionHash.insert(action, item);
        if(menu)
        {
            menu->addAction(action);
        }
    }

    return action;
}

void MainDialog::initAutoStartAction()
{
    QString application_name = QApplication::applicationName();
    QSettings settings("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat);
    QString application_path = QApplication::applicationFilePath();
    QString regeditPath = QDir::fromNativeSeparators(settings.value(application_name).toString());
    QString realPath = QDir::fromNativeSeparators(application_path);
    if(regeditPath.compare(realPath) == 0)
    {
        m_autoStart->setChecked(true);
    }
    else
    {
        m_autoStart->setChecked(false);
    }
}

void MainDialog::initRetryAction()
{
    QSettings settings(QSettings::IniFormat, QSettings::UserScope, "BrightGuo", QApplication::applicationName());
    if(settings.value("UseRetry").toBool())
    {
        m_retryAction->setChecked(true);
        m_retryMode = true;
    }
    else
    {
        m_retryAction->setChecked(false);
        m_retryMode = false;
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "build/build_config.h"

#if defined(OS_WIN)
#include <windows.h>
#include <shellapi.h>
#include <shlobj.h>
#endif

#include "chrome/common/chrome_paths.h"

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/sys_info.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"

namespace chrome {

// Gets the default user data directory, regardless of whether
// DIR_USER_DATA has been overridden by a command-line option.
bool GetDefaultUserDataDirectory(std::wstring* result) {
#if defined(OS_WIN)
  if (!PathService::Get(base::DIR_LOCAL_APP_DATA, result))
    return false;
#if defined(GOOGLE_CHROME_BUILD)
  file_util::AppendToPath(result, L"Google");
#endif
  file_util::AppendToPath(result, chrome::kBrowserAppName);
  file_util::AppendToPath(result, chrome::kUserDataDirname);
  return true;
#elif defined(OS_MACOSX)
  if (!PathService::Get(base::DIR_LOCAL_APP_DATA, result))
    return false;
  return true;
#elif defined(OS_LINUX)
  // TODO(port): Decide what to do on linux.
  NOTIMPLEMENTED();
  return false;
#endif  // defined(OS_WIN)
}

bool GetGearsPluginPathFromCommandLine(std::wstring *path) {
#ifndef NDEBUG
  // for debugging, support a cmd line based override
  *path = CommandLine::ForCurrentProcess()->GetSwitchValue(
              switches::kGearsPluginPathOverride);
  return !path->empty();
#else
  return false;
#endif
}

bool PathProvider(int key, FilePath* result) {
  // Some keys are just aliases...
  switch (key) {
    case chrome::DIR_APP:
      return PathService::Get(base::DIR_MODULE, result);
    case chrome::DIR_LOGS:
#ifndef NDEBUG
      return PathService::Get(chrome::DIR_USER_DATA, result);
#else
      return PathService::Get(base::DIR_EXE, result);
#endif
    case chrome::FILE_RESOURCE_MODULE:
      return PathService::Get(base::FILE_MODULE, result);
  }

  // Assume that we will not need to create the directory if it does not exist.
  // This flag can be set to true for the cases where we want to create it.
  bool create_dir = false;

  std::wstring cur;
  switch (key) {
    case chrome::DIR_USER_DATA:
      if (!GetDefaultUserDataDirectory(&cur))
        return false;
      create_dir = true;
      break;
    case chrome::DIR_USER_DOCUMENTS:
#if defined(OS_WIN)
      {
        wchar_t path_buf[MAX_PATH];
        if (FAILED(SHGetFolderPath(NULL, CSIDL_MYDOCUMENTS, NULL,
                                   SHGFP_TYPE_CURRENT, path_buf)))
          return false;
        cur.assign(path_buf);
      }
#else
      // TODO(port): Get the path (possibly using xdg-user-dirs)
      // or decide we don't need it on other platforms.
      NOTIMPLEMENTED();
      return false;
#endif
      create_dir = true;
      break;
    case chrome::DIR_DEFAULT_DOWNLOADS:
      // On Vista, we can get the download path using a Win API
      // (http://msdn.microsoft.com/en-us/library/bb762584(VS.85).aspx),
      // but it can be set to Desktop, which is dangerous. Instead,
      // we just use 'Downloads' under DIR_USER_DOCUMENTS. Localizing
      // 'downloads' is not a good idea because Chrome's UI language
      // can be changed.
      if (!PathService::Get(chrome::DIR_USER_DOCUMENTS, &cur))
        return false;
      file_util::AppendToPath(&cur, L"Downloads");
      // TODO(port): This will fail on other platforms unless we
      // implement DIR_USER_DOCUMENTS or use xdg-user-dirs to
      // get the download directory independently of DIR_USER_DOCUMENTS.
      break;
    case chrome::DIR_CRASH_DUMPS:
      // The crash reports are always stored relative to the default user data
      // directory.  This avoids the problem of having to re-initialize the
      // exception handler after parsing command line options, which may
      // override the location of the app's profile directory.
      if (!GetDefaultUserDataDirectory(&cur))
        return false;
      file_util::AppendToPath(&cur, L"Crash Reports");
      create_dir = true;
      break;
    case chrome::DIR_USER_DESKTOP:
#if defined(OS_WIN)
      {
        // We need to go compute the value. It would be nice to support paths
        // with names longer than MAX_PATH, but the system functions don't seem
        // to be designed for it either, with the exception of GetTempPath
        // (but other things will surely break if the temp path is too long,
        // so we don't bother handling it.
        wchar_t system_buffer[MAX_PATH];
        system_buffer[0] = 0;
        if (FAILED(SHGetFolderPath(NULL, CSIDL_DESKTOPDIRECTORY, NULL,
                                   SHGFP_TYPE_CURRENT, system_buffer)))
          return false;
        cur.assign(system_buffer);
      }
#else
      // TODO(port): Get the path (possibly using xdg-user-dirs)
      // or decide we don't need it on other platforms.
      NOTIMPLEMENTED();
      return false;
#endif
      break;
    case chrome::DIR_RESOURCES:
      if (!PathService::Get(chrome::DIR_APP, &cur))
        return false;
      file_util::AppendToPath(&cur, L"resources");
      create_dir = true;
      break;
    case chrome::DIR_INSPECTOR:
      if (!PathService::Get(chrome::DIR_APP, &cur))
        return false;
      file_util::AppendToPath(&cur, L"Resources");
      file_util::AppendToPath(&cur, L"Inspector");
      break;
    case chrome::DIR_THEMES:
      if (!PathService::Get(chrome::DIR_APP, &cur))
        return false;
      file_util::AppendToPath(&cur, L"themes");
      create_dir = true;
      break;
    case chrome::DIR_LOCALES:
      if (!PathService::Get(chrome::DIR_APP, &cur))
        return false;
      file_util::AppendToPath(&cur, L"locales");
      create_dir = true;
      break;
    case chrome::DIR_APP_DICTIONARIES:
      if (!PathService::Get(base::DIR_EXE, &cur))
        return false;
      file_util::AppendToPath(&cur, L"Dictionaries");
      create_dir = true;
      break;
    case chrome::FILE_LOCAL_STATE:
      if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
        return false;
      file_util::AppendToPath(&cur, chrome::kLocalStateFilename);
      break;
    case chrome::FILE_RECORDED_SCRIPT:
      if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
        return false;
      file_util::AppendToPath(&cur, L"script.log");
      break;
    case chrome::FILE_GEARS_PLUGIN:
      if (!GetGearsPluginPathFromCommandLine(&cur)) {
        // Search for gears.dll alongside chrome.dll first.  This new model
        // allows us to package gears.dll with the Chrome installer and update
        // it while Chrome is running.
        if (!PathService::Get(base::DIR_MODULE, &cur))
          return false;
        file_util::AppendToPath(&cur, L"gears.dll");

        if (!file_util::PathExists(cur)) {
          if (!PathService::Get(base::DIR_EXE, &cur))
            return false;
          file_util::AppendToPath(&cur, L"plugins");
          file_util::AppendToPath(&cur, L"gears");
          file_util::AppendToPath(&cur, L"gears.dll");
        }
      }
      break;
    // The following are only valid in the development environment, and
    // will fail if executed from an installed executable (because the
    // generated path won't exist).
    case chrome::DIR_TEST_DATA:
      if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur))
        return false;
      file_util::AppendToPath(&cur, L"chrome");
      file_util::AppendToPath(&cur, L"test");
      file_util::AppendToPath(&cur, L"data");
      if (!file_util::PathExists(cur))  // we don't want to create this
        return false;
      break;
    case chrome::DIR_TEST_TOOLS:
      if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur))
        return false;
      file_util::AppendToPath(&cur, L"chrome");
      file_util::AppendToPath(&cur, L"tools");
      file_util::AppendToPath(&cur, L"test");
      if (!file_util::PathExists(cur))  // we don't want to create this
        return false;
      break;
    case chrome::FILE_PYTHON_RUNTIME:
      if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur))
        return false;
      file_util::AppendToPath(&cur, L"third_party");
      file_util::AppendToPath(&cur, L"python_24");
      file_util::AppendToPath(&cur, L"python.exe");
      if (!file_util::PathExists(cur))  // we don't want to create this
        return false;
      break;
    case chrome::FILE_TEST_SERVER:
      if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur))
        return false;
      file_util::AppendToPath(&cur, L"net");
      file_util::AppendToPath(&cur, L"tools");
      file_util::AppendToPath(&cur, L"test");
      file_util::AppendToPath(&cur, L"testserver");
      file_util::AppendToPath(&cur, L"testserver.py");
      if (!file_util::PathExists(cur))  // we don't want to create this
        return false;
      break;
    default:
      return false;
  }

  if (create_dir && !file_util::PathExists(cur) && !file_util::CreateDirectory(cur))
    return false;

  *result = FilePath::FromWStringHack(cur);
  return true;
}

// This cannot be done as a static initializer sadly since Visual Studio will
// eliminate this object file if there is no direct entry point into it.
void RegisterPathProvider() {
  PathService::RegisterProvider(PathProvider, PATH_START, PATH_END);
}

}  // namespace chrome

<commit_msg>Port chrome_paths.cc to use FilePath.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "build/build_config.h"

#if defined(OS_WIN)
#include <windows.h>
#include <shellapi.h>
#include <shlobj.h>
#endif

#include "chrome/common/chrome_paths.h"

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/sys_info.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"

namespace chrome {

// Gets the default user data directory, regardless of whether
// DIR_USER_DATA has been overridden by a command-line option.
bool GetDefaultUserDataDirectory(FilePath* result) {
#if defined(OS_WIN)
  if (!PathService::Get(base::DIR_LOCAL_APP_DATA, result))
    return false;
#if defined(GOOGLE_CHROME_BUILD)
  *result = result->Append(FILE_PATH_LITERAL("Google"));
#endif
  *result = result->Append(chrome::kBrowserAppName);
  *result = result->Append(chrome::kUserDataDirname);
  return true;
#elif defined(OS_MACOSX)
  if (!PathService::Get(base::DIR_LOCAL_APP_DATA, result))
    return false;
  return true;
#elif defined(OS_LINUX)
  // TODO(port): Decide what to do on linux.
  NOTIMPLEMENTED();
  return false;
#endif  // defined(OS_WIN)
}

bool GetGearsPluginPathFromCommandLine(FilePath* path) {
#ifndef NDEBUG
  // for debugging, support a cmd line based override
  std::wstring plugin_path = CommandLine::ForCurrentProcess()->GetSwitchValue(
      switches::kGearsPluginPathOverride);
  // TODO(tc): After GetSwitchNativeValue lands, we don't need to use
  // FromWStringHack.
  *path = FilePath::FromWStringHack(plugin_path);
  return !plugin_path.empty();
#else
  return false;
#endif
}

bool PathProvider(int key, FilePath* result) {
  // Some keys are just aliases...
  switch (key) {
    case chrome::DIR_APP:
      return PathService::Get(base::DIR_MODULE, result);
    case chrome::DIR_LOGS:
#ifndef NDEBUG
      return PathService::Get(chrome::DIR_USER_DATA, result);
#else
      return PathService::Get(base::DIR_EXE, result);
#endif
    case chrome::FILE_RESOURCE_MODULE:
      return PathService::Get(base::FILE_MODULE, result);
  }

  // Assume that we will not need to create the directory if it does not exist.
  // This flag can be set to true for the cases where we want to create it.
  bool create_dir = false;

  FilePath cur;
  switch (key) {
    case chrome::DIR_USER_DATA:
      if (!GetDefaultUserDataDirectory(&cur))
        return false;
      create_dir = true;
      break;
    case chrome::DIR_USER_DOCUMENTS:
#if defined(OS_WIN)
      {
        wchar_t path_buf[MAX_PATH];
        if (FAILED(SHGetFolderPath(NULL, CSIDL_MYDOCUMENTS, NULL,
                                   SHGFP_TYPE_CURRENT, path_buf)))
          return false;
        cur = FilePath(path_buf);
      }
#else
      // TODO(port): Get the path (possibly using xdg-user-dirs)
      // or decide we don't need it on other platforms.
      NOTIMPLEMENTED();
      return false;
#endif
      create_dir = true;
      break;
    case chrome::DIR_DEFAULT_DOWNLOADS:
      // On Vista, we can get the download path using a Win API
      // (http://msdn.microsoft.com/en-us/library/bb762584(VS.85).aspx),
      // but it can be set to Desktop, which is dangerous. Instead,
      // we just use 'Downloads' under DIR_USER_DOCUMENTS. Localizing
      // 'downloads' is not a good idea because Chrome's UI language
      // can be changed.
      if (!PathService::Get(chrome::DIR_USER_DOCUMENTS, &cur))
        return false;
      cur = cur.Append(FILE_PATH_LITERAL("Downloads"));
      // TODO(port): This will fail on other platforms unless we
      // implement DIR_USER_DOCUMENTS or use xdg-user-dirs to
      // get the download directory independently of DIR_USER_DOCUMENTS.
      break;
    case chrome::DIR_CRASH_DUMPS:
      // The crash reports are always stored relative to the default user data
      // directory.  This avoids the problem of having to re-initialize the
      // exception handler after parsing command line options, which may
      // override the location of the app's profile directory.
      if (!GetDefaultUserDataDirectory(&cur))
        return false;
      cur = cur.Append(FILE_PATH_LITERAL("Crash Reports"));
      create_dir = true;
      break;
    case chrome::DIR_USER_DESKTOP:
#if defined(OS_WIN)
      {
        // We need to go compute the value. It would be nice to support paths
        // with names longer than MAX_PATH, but the system functions don't seem
        // to be designed for it either, with the exception of GetTempPath
        // (but other things will surely break if the temp path is too long,
        // so we don't bother handling it.
        wchar_t system_buffer[MAX_PATH];
        system_buffer[0] = 0;
        if (FAILED(SHGetFolderPath(NULL, CSIDL_DESKTOPDIRECTORY, NULL,
                                   SHGFP_TYPE_CURRENT, system_buffer)))
          return false;
        cur = FilePath(system_buffer);
      }
#else
      // TODO(port): Get the path (possibly using xdg-user-dirs)
      // or decide we don't need it on other platforms.
      NOTIMPLEMENTED();
      return false;
#endif
      break;
    case chrome::DIR_RESOURCES:
      if (!PathService::Get(chrome::DIR_APP, &cur))
        return false;
      cur = cur.Append(FILE_PATH_LITERAL("resources"));
      create_dir = true;
      break;
    case chrome::DIR_INSPECTOR:
      if (!PathService::Get(chrome::DIR_APP, &cur))
        return false;
      cur = cur.Append(FILE_PATH_LITERAL("Resources"));
      cur = cur.Append(FILE_PATH_LITERAL("Inspector"));
      break;
    case chrome::DIR_THEMES:
      if (!PathService::Get(chrome::DIR_APP, &cur))
        return false;
      cur = cur.Append(FILE_PATH_LITERAL("themes"));
      create_dir = true;
      break;
    case chrome::DIR_LOCALES:
      if (!PathService::Get(chrome::DIR_APP, &cur))
        return false;
      cur = cur.Append(FILE_PATH_LITERAL("locales"));
      create_dir = true;
      break;
    case chrome::DIR_APP_DICTIONARIES:
      if (!PathService::Get(base::DIR_EXE, &cur))
        return false;
      cur = cur.Append(FILE_PATH_LITERAL("Dictionaries"));
      create_dir = true;
      break;
    case chrome::FILE_LOCAL_STATE:
      if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
        return false;
      cur = cur.AppendASCII(WideToASCII(chrome::kLocalStateFilename));
      break;
    case chrome::FILE_RECORDED_SCRIPT:
      if (!PathService::Get(chrome::DIR_USER_DATA, &cur))
        return false;
      cur = cur.Append(FILE_PATH_LITERAL("script.log"));
      break;
    case chrome::FILE_GEARS_PLUGIN:
      if (!GetGearsPluginPathFromCommandLine(&cur)) {
        // Search for gears.dll alongside chrome.dll first.  This new model
        // allows us to package gears.dll with the Chrome installer and update
        // it while Chrome is running.
        if (!PathService::Get(base::DIR_MODULE, &cur))
          return false;
        cur = cur.Append(FILE_PATH_LITERAL("gears.dll"));

        if (!file_util::PathExists(cur)) {
          if (!PathService::Get(base::DIR_EXE, &cur))
            return false;
          cur = cur.Append(FILE_PATH_LITERAL("plugins"));
          cur = cur.Append(FILE_PATH_LITERAL("gears"));
          cur = cur.Append(FILE_PATH_LITERAL("gears.dll"));
        }
      }
      break;
    // The following are only valid in the development environment, and
    // will fail if executed from an installed executable (because the
    // generated path won't exist).
    case chrome::DIR_TEST_DATA:
      if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur))
        return false;
      cur = cur.Append(FILE_PATH_LITERAL("chrome"));
      cur = cur.Append(FILE_PATH_LITERAL("test"));
      cur = cur.Append(FILE_PATH_LITERAL("data"));
      if (!file_util::PathExists(cur))  // we don't want to create this
        return false;
      break;
    case chrome::DIR_TEST_TOOLS:
      if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur))
        return false;
      cur = cur.Append(FILE_PATH_LITERAL("chrome"));
      cur = cur.Append(FILE_PATH_LITERAL("tools"));
      cur = cur.Append(FILE_PATH_LITERAL("test"));
      if (!file_util::PathExists(cur))  // we don't want to create this
        return false;
      break;
    case chrome::FILE_PYTHON_RUNTIME:
      if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur))
        return false;
      cur = cur.Append(FILE_PATH_LITERAL("third_party"));
      cur = cur.Append(FILE_PATH_LITERAL("python_24"));
      cur = cur.Append(FILE_PATH_LITERAL("python.exe"));
      if (!file_util::PathExists(cur))  // we don't want to create this
        return false;
      break;
    case chrome::FILE_TEST_SERVER:
      if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur))
        return false;
      cur = cur.Append(FILE_PATH_LITERAL("net"));
      cur = cur.Append(FILE_PATH_LITERAL("tools"));
      cur = cur.Append(FILE_PATH_LITERAL("test"));
      cur = cur.Append(FILE_PATH_LITERAL("testserver"));
      cur = cur.Append(FILE_PATH_LITERAL("testserver.py"));
      if (!file_util::PathExists(cur))  // we don't want to create this
        return false;
      break;
    default:
      return false;
  }

  if (create_dir && !file_util::PathExists(cur) && !file_util::CreateDirectory(cur))
    return false;

  *result = cur;
  return true;
}

// This cannot be done as a static initializer sadly since Visual Studio will
// eliminate this object file if there is no direct entry point into it.
void RegisterPathProvider() {
  PathService::RegisterProvider(PathProvider, PATH_START, PATH_END);
}

}  // namespace chrome

<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/common/plugin_group.h"

#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "base/version.h"
#include "webkit/glue/plugins/plugin_list.h"

#if defined(OS_MACOSX)
// Plugin Groups for Mac.
// Plugins are listed here as soon as vulnerabilities and solutions
// (new versions) are published.
// TODO(panayiotis): Get the Real Player version on Mac, somehow.
static const PluginGroupDefinition kGroupDefinitions[] = {
  { "Quicktime", "QuickTime Plug-in", "", "", "7.6.6",
    "http://www.apple.com/quicktime/download/" },
  { "Java", "Java", "", "", "",
    "http://support.apple.com/kb/HT1338" },
  { "Flash", "Shockwave Flash", "", "", "10.1.82",
    "http://get.adobe.com/flashplayer/" },
  { "Silverlight 3", "Silverlight", "0", "4", "3.0.50106.0",
    "http://go.microsoft.com/fwlink/?LinkID=185927" },
  { "Silverlight 4", "Silverlight", "4", "5", "",
    "http://go.microsoft.com/fwlink/?LinkID=185927" },
  { "Flip4Mac", "Flip4Mac", "",  "", "2.2.1",
    "http://www.telestream.net/flip4mac-wmv/overview.htm" },
  { "Shockwave", "Shockwave for Director", "",  "", "11.5.7.609",
    "http://www.adobe.com/shockwave/download/" }
};

#elif defined(OS_WIN)
// TODO(panayiotis): We should group "RealJukebox NS Plugin" with the rest of
// the RealPlayer files.
static const PluginGroupDefinition kGroupDefinitions[] = {
  { "Quicktime", "QuickTime Plug-in", "", "", "7.6.7",
    "http://www.apple.com/quicktime/download/" },
  { "Java 6", "Java", "", "6", "6.0.200",
    "http://www.java.com/" },
  { "Adobe Reader 9", "Adobe Acrobat", "9", "10", "9.3.3",
    "http://get.adobe.com/reader/" },
  { "Adobe Reader 8", "Adobe Acrobat", "0", "9",  "8.2.3",
    "http://get.adobe.com/reader/" },
  { "Flash", "Shockwave Flash", "", "", "10.1.82",
    "http://get.adobe.com/flashplayer/" },
  { "Silverlight 3", "Silverlight", "0", "4", "3.0.50106.0",
    "http://go.microsoft.com/fwlink/?LinkID=185927" },
  { "Silverlight 4", "Silverlight", "4", "5", "",
    "http://go.microsoft.com/fwlink/?LinkID=185927" },
  { "Shockwave", "Shockwave for Director", "", "", "11.5.7.609",
    "http://www.adobe.com/shockwave/download/" },
  { "DivX Player", "DivX Web Player", "",  "", "1.4.3.4",
    "http://download.divx.com/divx/autoupdate/player/DivXWebPlayerInstaller.exe" },
  // These are here for grouping, no vulnerabilies known.
  { "Windows Media Player",  "Windows Media Player",  "",  "",   "", "" },
  { "Microsoft Office",  "Microsoft Office",  "",  "",   "", "" },
  // TODO(panayiotis): The vulnerable versions are
  //  (v >=  6.0.12.1040 && v <= 6.0.12.1663)
  //  || v == 6.0.12.1698  || v == 6.0.12.1741
  { "RealPlayer", "RealPlayer", "",  "",  "",
    "http://www.adobe.com/shockwave/download/" },
};

#else
static const PluginGroupDefinition kGroupDefinitions[] = {};
#endif

/*static*/
const PluginGroupDefinition* PluginGroup::GetPluginGroupDefinitions() {
  return kGroupDefinitions;
}

/*static*/
size_t PluginGroup::GetPluginGroupDefinitionsSize() {
  // TODO(viettrungluu): |arraysize()| doesn't work with zero-size arrays.
  return ARRAYSIZE_UNSAFE(kGroupDefinitions);
}

/*static*/
void PluginGroup::SetPolicyDisabledPluginSet(const std::set<string16>& set) {
  if (!policy_disabled_plugins_)
    policy_disabled_plugins_ = new std::set<string16>(set);
}

/*static*/
bool PluginGroup::IsPluginNameDisabledByPolicy(const string16& plugin_name) {
  return policy_disabled_plugins_ &&
      policy_disabled_plugins_->find(plugin_name) !=
          policy_disabled_plugins_->end();
}

/*static*/
bool PluginGroup::IsPluginPathDisabledByPolicy(const FilePath& plugin_path) {
  std::vector<WebPluginInfo> plugins;
  NPAPI::PluginList::Singleton()->GetPlugins(false, &plugins);
  for (std::vector<WebPluginInfo>::const_iterator it = plugins.begin();
       it != plugins.end();
       ++it) {
    if (FilePath::CompareEqualIgnoreCase(it->path.value(),
        plugin_path.value()) && IsPluginNameDisabledByPolicy(it->name)) {
      return true;
    }
  }
  return false;
}

PluginGroup::PluginGroup(const string16& group_name,
                         const string16& name_matcher,
                         const std::string& version_range_low,
                         const std::string& version_range_high,
                         const std::string& min_version,
                         const std::string& update_url) {
  group_name_ = group_name;
  name_matcher_ = name_matcher;
  version_range_low_str_ = version_range_low;
  if (!version_range_low.empty()) {
    version_range_low_.reset(
        Version::GetVersionFromString(version_range_low));
  }
  version_range_high_str_ = version_range_high;
  if (!version_range_high.empty()) {
    version_range_high_.reset(
        Version::GetVersionFromString(version_range_high));
  }
  min_version_str_ = min_version;
  if (!min_version.empty()) {
    min_version_.reset(Version::GetVersionFromString(min_version));
  }
  update_url_ = update_url;
  enabled_ = false;
  version_.reset(Version::GetVersionFromString("0"));
}

PluginGroup* PluginGroup::FromPluginGroupDefinition(
    const PluginGroupDefinition& definition) {
  return new PluginGroup(ASCIIToUTF16(definition.name),
                         ASCIIToUTF16(definition.name_matcher),
                         definition.version_matcher_low,
                         definition.version_matcher_high,
                         definition.min_version,
                         definition.update_url);
}

PluginGroup::~PluginGroup() { }

PluginGroup* PluginGroup::FromWebPluginInfo(const WebPluginInfo& wpi) {
  // Create a matcher from the name of this plugin.
  return new PluginGroup(wpi.name, wpi.name,
                         "", "", "", "");
}

PluginGroup* PluginGroup::FindHardcodedPluginGroup(const WebPluginInfo& info) {
  static std::vector<linked_ptr<PluginGroup> >* hardcoded_plugin_groups = NULL;
  if (!hardcoded_plugin_groups) {
    std::vector<linked_ptr<PluginGroup> >* groups =
        new std::vector<linked_ptr<PluginGroup> >();
    const PluginGroupDefinition* definitions = GetPluginGroupDefinitions();
    for (size_t i = 0; i < GetPluginGroupDefinitionsSize(); ++i) {
      PluginGroup* definition_group = PluginGroup::FromPluginGroupDefinition(
          definitions[i]);
      groups->push_back(linked_ptr<PluginGroup>(definition_group));
    }
    hardcoded_plugin_groups = groups;
  }

  // See if this plugin matches any of the hardcoded groups.
  PluginGroup* hardcoded_group = FindGroupMatchingPlugin(
      *hardcoded_plugin_groups, info);
  if (hardcoded_group) {
    // Make a copy.
    return hardcoded_group->Copy();
  } else {
    // Not found in our hardcoded list, create a new one.
    return PluginGroup::FromWebPluginInfo(info);
  }
}

PluginGroup* PluginGroup::FindGroupMatchingPlugin(
    std::vector<linked_ptr<PluginGroup> >& plugin_groups,
    const WebPluginInfo& plugin) {
  for (std::vector<linked_ptr<PluginGroup> >::iterator it =
       plugin_groups.begin();
       it != plugin_groups.end();
       ++it) {
    if ((*it)->Match(plugin)) {
      return it->get();
    }
  }
  return NULL;
}

bool PluginGroup::Match(const WebPluginInfo& plugin) const {
  if (name_matcher_.empty()) {
    return false;
  }

  // Look for the name matcher anywhere in the plugin name.
  if (plugin.name.find(name_matcher_) == string16::npos) {
    return false;
  }

  if (version_range_low_.get() == NULL ||
      version_range_high_.get() == NULL) {
    return true;
  }

  // There's a version range, we must be in it.
  scoped_ptr<Version> plugin_version(
      Version::GetVersionFromString(UTF16ToWide(plugin.version)));
  if (plugin_version.get() == NULL) {
    // No version could be extracted, assume we don't match the range.
    return false;
  }

  // We match if we are in the range: [low, high)
  return (version_range_low_->CompareTo(*plugin_version) <= 0 &&
          version_range_high_->CompareTo(*plugin_version) > 0);
}

void PluginGroup::UpdateDescriptionAndVersion(const WebPluginInfo& plugin) {
  description_ = plugin.desc;

  // Update |version_|. Remove spaces and ')' from the version string,
  // Replace any instances of 'r', ',' or '(' with a dot.
  std::wstring version = UTF16ToWide(plugin.version);
  RemoveChars(version, L") ", &version);
  std::replace(version.begin(), version.end(), 'r', '.');
  std::replace(version.begin(), version.end(), ',', '.');
  std::replace(version.begin(), version.end(), '(', '.');

  if (Version* new_version = Version::GetVersionFromString(version))
    version_.reset(new_version);
  else
    version_.reset(Version::GetVersionFromString("0"));
}

void PluginGroup::AddPlugin(const WebPluginInfo& plugin, int position) {
  web_plugin_infos_.push_back(plugin);
  // The position of this plugin relative to the global list of plugins.
  web_plugin_positions_.push_back(position);

  // A group is enabled if any of the files are enabled.
  if (plugin.enabled) {
    if (!enabled_) {
      // If this is the first enabled plugin, use its description.
      enabled_ = true;
      UpdateDescriptionAndVersion(plugin);
    }
  } else {
    // If this is the first plugin and it's disabled,
    // use its description for now.
    if (description_.empty())
      UpdateDescriptionAndVersion(plugin);
  }
}

DictionaryValue* PluginGroup::GetSummary() const {
  DictionaryValue* result = new DictionaryValue();
  result->SetString("name", group_name_);
  result->SetBoolean("enabled", enabled_);
  return result;
}

DictionaryValue* PluginGroup::GetDataForUI() const {
  DictionaryValue* result = new DictionaryValue();
  result->SetString("name", group_name_);
  result->SetString("description", description_);
  result->SetString("version", version_->GetString());
  result->SetString("update_url", update_url_);
  result->SetBoolean("critical", IsVulnerable());

  bool group_disabled_by_policy = IsPluginNameDisabledByPolicy(group_name_);
  if (group_disabled_by_policy) {
    result->SetString("enabledMode", "disabledByPolicy");
  } else {
    result->SetString("enabledMode", enabled_ ? "enabled" : "disabledByUser");
  }

  ListValue* plugin_files = new ListValue();
  for (size_t i = 0; i < web_plugin_infos_.size(); ++i) {
    const WebPluginInfo& web_plugin = web_plugin_infos_[i];
    int priority = web_plugin_positions_[i];
    DictionaryValue* plugin_file = new DictionaryValue();
    plugin_file->SetString("name", web_plugin.name);
    plugin_file->SetString("description", web_plugin.desc);
    plugin_file->SetString("path", web_plugin.path.value());
    plugin_file->SetString("version", web_plugin.version);
    bool plugin_disabled_by_policy = group_disabled_by_policy ||
        IsPluginNameDisabledByPolicy(web_plugin.name);
    if (plugin_disabled_by_policy) {
      plugin_file->SetString("enabledMode", "disabledByPolicy");
    } else {
      plugin_file->SetString("enabledMode",
                             web_plugin.enabled ? "enabled" : "disabledByUser");
    }
    plugin_file->SetInteger("priority", priority);

    ListValue* mime_types = new ListValue();
    for (std::vector<WebPluginMimeType>::const_iterator type_it =
         web_plugin.mime_types.begin();
         type_it != web_plugin.mime_types.end();
         ++type_it) {
      DictionaryValue* mime_type = new DictionaryValue();
      mime_type->SetString("mimeType", type_it->mime_type);
      mime_type->SetString("description", type_it->description);

      ListValue* file_extensions = new ListValue();
      for (std::vector<std::string>::const_iterator ext_it =
           type_it->file_extensions.begin();
           ext_it != type_it->file_extensions.end();
           ++ext_it) {
        file_extensions->Append(new StringValue(*ext_it));
      }
      mime_type->Set("fileExtensions", file_extensions);

      mime_types->Append(mime_type);
    }
    plugin_file->Set("mimeTypes", mime_types);

    plugin_files->Append(plugin_file);
  }
  result->Set("plugin_files", plugin_files);

  return result;
}

// Returns true if the latest version of this plugin group is vulnerable.
bool PluginGroup::IsVulnerable() const {
  if (min_version_.get() == NULL || version_->GetString() == "0") {
    return false;
  }
  return version_->CompareTo(*min_version_) < 0;
}

void PluginGroup::Enable(bool enable) {
  for (std::vector<WebPluginInfo>::const_iterator it =
       web_plugin_infos_.begin();
       it != web_plugin_infos_.end(); ++it) {
    if (enable && !IsPluginNameDisabledByPolicy(it->name)) {
      NPAPI::PluginList::Singleton()->EnablePlugin(FilePath(it->path));
    } else {
      NPAPI::PluginList::Singleton()->DisablePlugin(FilePath(it->path));
    }
  }
}
<commit_msg>compile fix<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/common/plugin_group.h"

#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "base/version.h"
#include "webkit/glue/plugins/plugin_list.h"

#if defined(OS_MACOSX)
// Plugin Groups for Mac.
// Plugins are listed here as soon as vulnerabilities and solutions
// (new versions) are published.
// TODO(panayiotis): Get the Real Player version on Mac, somehow.
static const PluginGroupDefinition kGroupDefinitions[] = {
  { "Quicktime", "QuickTime Plug-in", "", "", "7.6.6",
    "http://www.apple.com/quicktime/download/" },
  { "Java", "Java", "", "", "",
    "http://support.apple.com/kb/HT1338" },
  { "Flash", "Shockwave Flash", "", "", "10.1.82",
    "http://get.adobe.com/flashplayer/" },
  { "Silverlight 3", "Silverlight", "0", "4", "3.0.50106.0",
    "http://go.microsoft.com/fwlink/?LinkID=185927" },
  { "Silverlight 4", "Silverlight", "4", "5", "",
    "http://go.microsoft.com/fwlink/?LinkID=185927" },
  { "Flip4Mac", "Flip4Mac", "",  "", "2.2.1",
    "http://www.telestream.net/flip4mac-wmv/overview.htm" },
  { "Shockwave", "Shockwave for Director", "",  "", "11.5.7.609",
    "http://www.adobe.com/shockwave/download/" }
};

#elif defined(OS_WIN)
// TODO(panayiotis): We should group "RealJukebox NS Plugin" with the rest of
// the RealPlayer files.
static const PluginGroupDefinition kGroupDefinitions[] = {
  { "Quicktime", "QuickTime Plug-in", "", "", "7.6.7",
    "http://www.apple.com/quicktime/download/" },
  { "Java 6", "Java", "", "6", "6.0.200",
    "http://www.java.com/" },
  { "Adobe Reader 9", "Adobe Acrobat", "9", "10", "9.3.3",
    "http://get.adobe.com/reader/" },
  { "Adobe Reader 8", "Adobe Acrobat", "0", "9",  "8.2.3",
    "http://get.adobe.com/reader/" },
  { "Flash", "Shockwave Flash", "", "", "10.1.82",
    "http://get.adobe.com/flashplayer/" },
  { "Silverlight 3", "Silverlight", "0", "4", "3.0.50106.0",
    "http://go.microsoft.com/fwlink/?LinkID=185927" },
  { "Silverlight 4", "Silverlight", "4", "5", "",
    "http://go.microsoft.com/fwlink/?LinkID=185927" },
  { "Shockwave", "Shockwave for Director", "", "", "11.5.7.609",
    "http://www.adobe.com/shockwave/download/" },
  { "DivX Player", "DivX Web Player", "",  "", "1.4.3.4",
    "http://download.divx.com/divx/autoupdate/player/DivXWebPlayerInstaller.exe" },
  // These are here for grouping, no vulnerabilies known.
  { "Windows Media Player",  "Windows Media Player",  "",  "",   "", "" },
  { "Microsoft Office",  "Microsoft Office",  "",  "",   "", "" },
  // TODO(panayiotis): The vulnerable versions are
  //  (v >=  6.0.12.1040 && v <= 6.0.12.1663)
  //  || v == 6.0.12.1698  || v == 6.0.12.1741
  { "RealPlayer", "RealPlayer", "",  "",  "",
    "http://www.adobe.com/shockwave/download/" },
};

#else
static const PluginGroupDefinition kGroupDefinitions[] = {};
#endif

/*static*/
std::set<string16>* PluginGroup::policy_disabled_plugins_;

/*static*/
const PluginGroupDefinition* PluginGroup::GetPluginGroupDefinitions() {
  return kGroupDefinitions;
}

/*static*/
size_t PluginGroup::GetPluginGroupDefinitionsSize() {
  // TODO(viettrungluu): |arraysize()| doesn't work with zero-size arrays.
  return ARRAYSIZE_UNSAFE(kGroupDefinitions);
}

/*static*/
void PluginGroup::SetPolicyDisabledPluginSet(const std::set<string16>& set) {
  if (!policy_disabled_plugins_)
    policy_disabled_plugins_ = new std::set<string16>(set);
}

/*static*/
bool PluginGroup::IsPluginNameDisabledByPolicy(const string16& plugin_name) {
  return policy_disabled_plugins_ &&
      policy_disabled_plugins_->find(plugin_name) !=
          policy_disabled_plugins_->end();
}

/*static*/
bool PluginGroup::IsPluginPathDisabledByPolicy(const FilePath& plugin_path) {
  std::vector<WebPluginInfo> plugins;
  NPAPI::PluginList::Singleton()->GetPlugins(false, &plugins);
  for (std::vector<WebPluginInfo>::const_iterator it = plugins.begin();
       it != plugins.end();
       ++it) {
    if (FilePath::CompareEqualIgnoreCase(it->path.value(),
        plugin_path.value()) && IsPluginNameDisabledByPolicy(it->name)) {
      return true;
    }
  }
  return false;
}

PluginGroup::PluginGroup(const string16& group_name,
                         const string16& name_matcher,
                         const std::string& version_range_low,
                         const std::string& version_range_high,
                         const std::string& min_version,
                         const std::string& update_url) {
  group_name_ = group_name;
  name_matcher_ = name_matcher;
  version_range_low_str_ = version_range_low;
  if (!version_range_low.empty()) {
    version_range_low_.reset(
        Version::GetVersionFromString(version_range_low));
  }
  version_range_high_str_ = version_range_high;
  if (!version_range_high.empty()) {
    version_range_high_.reset(
        Version::GetVersionFromString(version_range_high));
  }
  min_version_str_ = min_version;
  if (!min_version.empty()) {
    min_version_.reset(Version::GetVersionFromString(min_version));
  }
  update_url_ = update_url;
  enabled_ = false;
  version_.reset(Version::GetVersionFromString("0"));
}

PluginGroup* PluginGroup::FromPluginGroupDefinition(
    const PluginGroupDefinition& definition) {
  return new PluginGroup(ASCIIToUTF16(definition.name),
                         ASCIIToUTF16(definition.name_matcher),
                         definition.version_matcher_low,
                         definition.version_matcher_high,
                         definition.min_version,
                         definition.update_url);
}

PluginGroup::~PluginGroup() { }

PluginGroup* PluginGroup::FromWebPluginInfo(const WebPluginInfo& wpi) {
  // Create a matcher from the name of this plugin.
  return new PluginGroup(wpi.name, wpi.name,
                         "", "", "", "");
}

PluginGroup* PluginGroup::FindHardcodedPluginGroup(const WebPluginInfo& info) {
  static std::vector<linked_ptr<PluginGroup> >* hardcoded_plugin_groups = NULL;
  if (!hardcoded_plugin_groups) {
    std::vector<linked_ptr<PluginGroup> >* groups =
        new std::vector<linked_ptr<PluginGroup> >();
    const PluginGroupDefinition* definitions = GetPluginGroupDefinitions();
    for (size_t i = 0; i < GetPluginGroupDefinitionsSize(); ++i) {
      PluginGroup* definition_group = PluginGroup::FromPluginGroupDefinition(
          definitions[i]);
      groups->push_back(linked_ptr<PluginGroup>(definition_group));
    }
    hardcoded_plugin_groups = groups;
  }

  // See if this plugin matches any of the hardcoded groups.
  PluginGroup* hardcoded_group = FindGroupMatchingPlugin(
      *hardcoded_plugin_groups, info);
  if (hardcoded_group) {
    // Make a copy.
    return hardcoded_group->Copy();
  } else {
    // Not found in our hardcoded list, create a new one.
    return PluginGroup::FromWebPluginInfo(info);
  }
}

PluginGroup* PluginGroup::FindGroupMatchingPlugin(
    std::vector<linked_ptr<PluginGroup> >& plugin_groups,
    const WebPluginInfo& plugin) {
  for (std::vector<linked_ptr<PluginGroup> >::iterator it =
       plugin_groups.begin();
       it != plugin_groups.end();
       ++it) {
    if ((*it)->Match(plugin)) {
      return it->get();
    }
  }
  return NULL;
}

bool PluginGroup::Match(const WebPluginInfo& plugin) const {
  if (name_matcher_.empty()) {
    return false;
  }

  // Look for the name matcher anywhere in the plugin name.
  if (plugin.name.find(name_matcher_) == string16::npos) {
    return false;
  }

  if (version_range_low_.get() == NULL ||
      version_range_high_.get() == NULL) {
    return true;
  }

  // There's a version range, we must be in it.
  scoped_ptr<Version> plugin_version(
      Version::GetVersionFromString(UTF16ToWide(plugin.version)));
  if (plugin_version.get() == NULL) {
    // No version could be extracted, assume we don't match the range.
    return false;
  }

  // We match if we are in the range: [low, high)
  return (version_range_low_->CompareTo(*plugin_version) <= 0 &&
          version_range_high_->CompareTo(*plugin_version) > 0);
}

void PluginGroup::UpdateDescriptionAndVersion(const WebPluginInfo& plugin) {
  description_ = plugin.desc;

  // Update |version_|. Remove spaces and ')' from the version string,
  // Replace any instances of 'r', ',' or '(' with a dot.
  std::wstring version = UTF16ToWide(plugin.version);
  RemoveChars(version, L") ", &version);
  std::replace(version.begin(), version.end(), 'r', '.');
  std::replace(version.begin(), version.end(), ',', '.');
  std::replace(version.begin(), version.end(), '(', '.');

  if (Version* new_version = Version::GetVersionFromString(version))
    version_.reset(new_version);
  else
    version_.reset(Version::GetVersionFromString("0"));
}

void PluginGroup::AddPlugin(const WebPluginInfo& plugin, int position) {
  web_plugin_infos_.push_back(plugin);
  // The position of this plugin relative to the global list of plugins.
  web_plugin_positions_.push_back(position);

  // A group is enabled if any of the files are enabled.
  if (plugin.enabled) {
    if (!enabled_) {
      // If this is the first enabled plugin, use its description.
      enabled_ = true;
      UpdateDescriptionAndVersion(plugin);
    }
  } else {
    // If this is the first plugin and it's disabled,
    // use its description for now.
    if (description_.empty())
      UpdateDescriptionAndVersion(plugin);
  }
}

DictionaryValue* PluginGroup::GetSummary() const {
  DictionaryValue* result = new DictionaryValue();
  result->SetString("name", group_name_);
  result->SetBoolean("enabled", enabled_);
  return result;
}

DictionaryValue* PluginGroup::GetDataForUI() const {
  DictionaryValue* result = new DictionaryValue();
  result->SetString("name", group_name_);
  result->SetString("description", description_);
  result->SetString("version", version_->GetString());
  result->SetString("update_url", update_url_);
  result->SetBoolean("critical", IsVulnerable());

  bool group_disabled_by_policy = IsPluginNameDisabledByPolicy(group_name_);
  if (group_disabled_by_policy) {
    result->SetString("enabledMode", "disabledByPolicy");
  } else {
    result->SetString("enabledMode", enabled_ ? "enabled" : "disabledByUser");
  }

  ListValue* plugin_files = new ListValue();
  for (size_t i = 0; i < web_plugin_infos_.size(); ++i) {
    const WebPluginInfo& web_plugin = web_plugin_infos_[i];
    int priority = web_plugin_positions_[i];
    DictionaryValue* plugin_file = new DictionaryValue();
    plugin_file->SetString("name", web_plugin.name);
    plugin_file->SetString("description", web_plugin.desc);
    plugin_file->SetString("path", web_plugin.path.value());
    plugin_file->SetString("version", web_plugin.version);
    bool plugin_disabled_by_policy = group_disabled_by_policy ||
        IsPluginNameDisabledByPolicy(web_plugin.name);
    if (plugin_disabled_by_policy) {
      plugin_file->SetString("enabledMode", "disabledByPolicy");
    } else {
      plugin_file->SetString("enabledMode",
                             web_plugin.enabled ? "enabled" : "disabledByUser");
    }
    plugin_file->SetInteger("priority", priority);

    ListValue* mime_types = new ListValue();
    for (std::vector<WebPluginMimeType>::const_iterator type_it =
         web_plugin.mime_types.begin();
         type_it != web_plugin.mime_types.end();
         ++type_it) {
      DictionaryValue* mime_type = new DictionaryValue();
      mime_type->SetString("mimeType", type_it->mime_type);
      mime_type->SetString("description", type_it->description);

      ListValue* file_extensions = new ListValue();
      for (std::vector<std::string>::const_iterator ext_it =
           type_it->file_extensions.begin();
           ext_it != type_it->file_extensions.end();
           ++ext_it) {
        file_extensions->Append(new StringValue(*ext_it));
      }
      mime_type->Set("fileExtensions", file_extensions);

      mime_types->Append(mime_type);
    }
    plugin_file->Set("mimeTypes", mime_types);

    plugin_files->Append(plugin_file);
  }
  result->Set("plugin_files", plugin_files);

  return result;
}

// Returns true if the latest version of this plugin group is vulnerable.
bool PluginGroup::IsVulnerable() const {
  if (min_version_.get() == NULL || version_->GetString() == "0") {
    return false;
  }
  return version_->CompareTo(*min_version_) < 0;
}

void PluginGroup::Enable(bool enable) {
  for (std::vector<WebPluginInfo>::const_iterator it =
       web_plugin_infos_.begin();
       it != web_plugin_infos_.end(); ++it) {
    if (enable && !IsPluginNameDisabledByPolicy(it->name)) {
      NPAPI::PluginList::Singleton()->EnablePlugin(FilePath(it->path));
    } else {
      NPAPI::PluginList::Singleton()->DisablePlugin(FilePath(it->path));
    }
  }
}
<|endoftext|>