Implemented project manager, app data, welcome window
This commit is contained in:
		
							
								
								
									
										11
									
								
								Ember.pro
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								Ember.pro
									
									
									
									
									
								
							@@ -31,7 +31,8 @@ SOURCES += \
 | 
			
		||||
    model/project.cpp \
 | 
			
		||||
    model/projectitem.cpp \
 | 
			
		||||
    storage/appdatastorage.cpp \
 | 
			
		||||
    business/projectmanager.cpp
 | 
			
		||||
    business/projectmanager.cpp \
 | 
			
		||||
    ui/welcome/recentprojectwidget.cpp
 | 
			
		||||
 | 
			
		||||
HEADERS += \
 | 
			
		||||
    ui/welcome/welcomedialog.h \
 | 
			
		||||
@@ -41,11 +42,13 @@ HEADERS += \
 | 
			
		||||
    model/projectitem.h \
 | 
			
		||||
    properties/config.h \
 | 
			
		||||
    storage/appdatastorage.h \
 | 
			
		||||
    business/projectmanager.h
 | 
			
		||||
    business/projectmanager.h \
 | 
			
		||||
    ui/welcome/recentprojectwidget.h
 | 
			
		||||
 | 
			
		||||
FORMS += \
 | 
			
		||||
    ui/welcome/welcomedialog.ui \
 | 
			
		||||
    ui/dialogs/newprojectdialog.ui
 | 
			
		||||
    ui/dialogs/newprojectdialog.ui \
 | 
			
		||||
    ui/welcome/recentprojectwidget.ui
 | 
			
		||||
 | 
			
		||||
RESOURCES += \
 | 
			
		||||
    resources/appresources.qrc
 | 
			
		||||
@@ -53,3 +56,5 @@ RESOURCES += \
 | 
			
		||||
LIBS += -lboost_filesystem
 | 
			
		||||
LIBS += -lboost_system
 | 
			
		||||
LIBS += -lpugixml
 | 
			
		||||
 | 
			
		||||
CONFIG += c++14
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,63 @@
 | 
			
		||||
#include "projectmanager.h"
 | 
			
		||||
#include <storage/appdatastorage.h>
 | 
			
		||||
 | 
			
		||||
namespace Ember
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
ProjectManager::ProjectManager()
 | 
			
		||||
    : m_currentProject(nullptr),
 | 
			
		||||
      m_recentProjects(),
 | 
			
		||||
      m_recentProjectsLoaded(false)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const ProjectManager::RecentProjectMap &ProjectManager::recentProjects()
 | 
			
		||||
{
 | 
			
		||||
    if (!m_recentProjectsLoaded)
 | 
			
		||||
    {
 | 
			
		||||
        std::vector<RecentProject> projects;
 | 
			
		||||
        AppDataStorage::readRecentProjects(projects);
 | 
			
		||||
 | 
			
		||||
        for (RecentProject& project : projects)
 | 
			
		||||
            m_recentProjects.emplace(project.path, project);
 | 
			
		||||
 | 
			
		||||
        m_recentProjectsLoaded = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return m_recentProjects;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ProjectManager::pinRecentProject(boost::filesystem::path path, bool pinned)
 | 
			
		||||
{
 | 
			
		||||
    auto it = m_recentProjects.find(path);
 | 
			
		||||
    if (it != m_recentProjects.end())
 | 
			
		||||
    {
 | 
			
		||||
        if (it->second.pinned != pinned)
 | 
			
		||||
        {
 | 
			
		||||
            it->second.pinned = pinned;
 | 
			
		||||
            saveRecentProjects();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ProjectManager::deleteRecentProject(boost::filesystem::path path)
 | 
			
		||||
{
 | 
			
		||||
    auto it = m_recentProjects.find(path);
 | 
			
		||||
    if (it != m_recentProjects.end())
 | 
			
		||||
    {
 | 
			
		||||
        m_recentProjects.erase(it);
 | 
			
		||||
        saveRecentProjects();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ProjectManager::saveRecentProjects()
 | 
			
		||||
{
 | 
			
		||||
    std::vector<RecentProject> projects;
 | 
			
		||||
    for (auto pair : m_recentProjects)
 | 
			
		||||
        projects.push_back(pair.second);
 | 
			
		||||
 | 
			
		||||
    AppDataStorage::storeRecentProjects(projects);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,49 @@
 | 
			
		||||
#ifndef PROJECTMANAGER_H
 | 
			
		||||
#define PROJECTMANAGER_H
 | 
			
		||||
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <model/project.h>
 | 
			
		||||
 | 
			
		||||
namespace Ember
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class ProjectManager
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    typedef std::map<boost::filesystem::path, RecentProject> RecentProjectMap;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Constructor
 | 
			
		||||
     */
 | 
			
		||||
    ProjectManager();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Gets a list of recent projects. First time reads from disk.
 | 
			
		||||
     * @return Map of recent projects.
 | 
			
		||||
     */
 | 
			
		||||
    const RecentProjectMap& recentProjects();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Pins or unpins a recent project. Updates storage as well.
 | 
			
		||||
     * @param path Path
 | 
			
		||||
     * @param pinned True to pin, false to unpin
 | 
			
		||||
     */
 | 
			
		||||
    void pinRecentProject(boost::filesystem::path path, bool pinned = true);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Deletes a recent project.
 | 
			
		||||
     * @param path
 | 
			
		||||
     */
 | 
			
		||||
    void deleteRecentProject(boost::filesystem::path path);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    void saveRecentProjects();
 | 
			
		||||
 | 
			
		||||
    Project* m_currentProject;
 | 
			
		||||
    RecentProjectMap m_recentProjects;
 | 
			
		||||
    bool m_recentProjectsLoaded;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								main.cpp
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								main.cpp
									
									
									
									
									
								
							@@ -1,5 +1,7 @@
 | 
			
		||||
#include <QApplication>
 | 
			
		||||
#include "ui/mainwindow.h"
 | 
			
		||||
#include <storage/appdatastorage.h>
 | 
			
		||||
#include <business/projectmanager.h>
 | 
			
		||||
#include <ui/mainwindow.h>
 | 
			
		||||
#include <properties/config.h>
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[])
 | 
			
		||||
@@ -9,7 +11,11 @@ int main(int argc, char *argv[])
 | 
			
		||||
    a.setApplicationDisplayName(APP_NAME);
 | 
			
		||||
    a.setApplicationVersion(APP_VERSION);
 | 
			
		||||
 | 
			
		||||
    MainWindow w;
 | 
			
		||||
    Ember::AppDataStorage::initialize();
 | 
			
		||||
 | 
			
		||||
    Ember::ProjectManager projectManager;
 | 
			
		||||
 | 
			
		||||
    Ember::MainWindow w(&projectManager);
 | 
			
		||||
    w.show();
 | 
			
		||||
 | 
			
		||||
    return a.exec();
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,11 @@ ProjectItem::ProjectItem(boost::filesystem::path path, ProjectItem* parent, Proj
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ProjectItem::~ProjectItem()
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ProjectItem::name() const
 | 
			
		||||
{
 | 
			
		||||
    return m_path.filename().string();
 | 
			
		||||
 
 | 
			
		||||
@@ -33,6 +33,11 @@ public:
 | 
			
		||||
     */
 | 
			
		||||
    ProjectItem(boost::filesystem::path path, ProjectItem* parent, Project* project);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Destructor
 | 
			
		||||
     */
 | 
			
		||||
    virtual ~ProjectItem();
 | 
			
		||||
 | 
			
		||||
    // Getters
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Gets the name of the item
 | 
			
		||||
 
 | 
			
		||||
@@ -8,20 +8,23 @@
 | 
			
		||||
namespace Ember
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
AppDataStorage::AppDataStorage()
 | 
			
		||||
boost::filesystem::path AppDataStorage::s_appData;
 | 
			
		||||
boost::filesystem::path AppDataStorage::s_recentProjects;
 | 
			
		||||
 | 
			
		||||
void AppDataStorage::initialize()
 | 
			
		||||
{
 | 
			
		||||
    QString appData = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
 | 
			
		||||
    m_appData = appData.toStdString();
 | 
			
		||||
    m_recentProjects = m_appData;
 | 
			
		||||
    m_recentProjects += RECENT_PROJECTS_FILENAME;
 | 
			
		||||
    s_appData = appData.toStdString();
 | 
			
		||||
    s_recentProjects = s_appData;
 | 
			
		||||
    s_recentProjects += RECENT_PROJECTS_FILENAME;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AppDataStorage::readRecentProjects(std::vector<RecentProject> &projects)
 | 
			
		||||
{
 | 
			
		||||
    if (boost::filesystem::exists(m_recentProjects))
 | 
			
		||||
    if (boost::filesystem::exists(s_recentProjects))
 | 
			
		||||
    {
 | 
			
		||||
        pugi::xml_document doc;
 | 
			
		||||
        doc.load_file(m_recentProjects.c_str());
 | 
			
		||||
        doc.load_file(s_recentProjects.c_str());
 | 
			
		||||
 | 
			
		||||
        for (auto& node : doc.document_element())
 | 
			
		||||
        {
 | 
			
		||||
@@ -54,8 +57,8 @@ void AppDataStorage::storeRecentProjects(const std::vector<RecentProject> &proje
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Save file, ensure directory exists
 | 
			
		||||
    boost::filesystem::create_directories(m_appData);
 | 
			
		||||
    doc.save_file(m_recentProjects.string().c_str());
 | 
			
		||||
    boost::filesystem::create_directories(s_appData);
 | 
			
		||||
    doc.save_file(s_recentProjects.string().c_str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -12,23 +12,23 @@ namespace Ember
 | 
			
		||||
class AppDataStorage
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    AppDataStorage();
 | 
			
		||||
    static void initialize();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Reads recent projects
 | 
			
		||||
     * @param projects List will be saved to given vector.
 | 
			
		||||
     */
 | 
			
		||||
    void readRecentProjects(std::vector<RecentProject>& projects);
 | 
			
		||||
    static void readRecentProjects(std::vector<RecentProject>& projects);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Stores recent projects
 | 
			
		||||
     * @param projects List of projects.
 | 
			
		||||
     */
 | 
			
		||||
    void storeRecentProjects(const std::vector<RecentProject>& projects);
 | 
			
		||||
    static void storeRecentProjects(const std::vector<RecentProject>& projects);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    boost::filesystem::path m_appData;
 | 
			
		||||
    boost::filesystem::path m_recentProjects;
 | 
			
		||||
    static boost::filesystem::path s_appData;
 | 
			
		||||
    static boost::filesystem::path s_recentProjects;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,60 @@
 | 
			
		||||
#include <QTimer>
 | 
			
		||||
#include <ui/welcome/welcomedialog.h>
 | 
			
		||||
 | 
			
		||||
#include "mainwindow.h"
 | 
			
		||||
#include "ui_mainwindow.h"
 | 
			
		||||
 | 
			
		||||
MainWindow::MainWindow(QWidget *parent) :
 | 
			
		||||
    QMainWindow(parent)
 | 
			
		||||
namespace Ember
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
MainWindow::MainWindow(ProjectManager* projectManager, QWidget *parent) :
 | 
			
		||||
    QMainWindow(parent),
 | 
			
		||||
    m_projectManager(projectManager)
 | 
			
		||||
{
 | 
			
		||||
    setupUi();
 | 
			
		||||
    setupActions();
 | 
			
		||||
    QTimer::singleShot(0, this, &MainWindow::showWelcomeDialog);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MainWindow::~MainWindow()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWindow::setupUi()
 | 
			
		||||
{
 | 
			
		||||
    QWidget* central = new QWidget();
 | 
			
		||||
    setCentralWidget(central);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWindow::setupActions()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWindow::showWelcomeDialog()
 | 
			
		||||
{
 | 
			
		||||
    WelcomeDialog dialog(m_projectManager, this);
 | 
			
		||||
    if (dialog.exec() == QDialog::Accepted)
 | 
			
		||||
    {
 | 
			
		||||
        switch(dialog.resultAction())
 | 
			
		||||
        {
 | 
			
		||||
            case WelcomeDialog::NEW_PROJECT:
 | 
			
		||||
                newProject();
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            case WelcomeDialog::OPEN_PROJECT:
 | 
			
		||||
                openProject(dialog.openPath());
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWindow::newProject()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MainWindow::openProject(boost::filesystem::path path)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,18 +1,33 @@
 | 
			
		||||
#ifndef MAINWINDOW_H
 | 
			
		||||
#define MAINWINDOW_H
 | 
			
		||||
 | 
			
		||||
#include <boost/filesystem.hpp>
 | 
			
		||||
#include <QMainWindow>
 | 
			
		||||
 | 
			
		||||
#include <business/projectmanager.h>
 | 
			
		||||
 | 
			
		||||
namespace Ember
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class MainWindow : public QMainWindow
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    explicit MainWindow(QWidget *parent = 0);
 | 
			
		||||
    ~MainWindow();
 | 
			
		||||
    explicit MainWindow(ProjectManager* projectManager, QWidget *parent = 0);
 | 
			
		||||
    virtual ~MainWindow();
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
    void showWelcomeDialog();
 | 
			
		||||
    void newProject();
 | 
			
		||||
    void openProject(boost::filesystem::path path);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    void setupUi();
 | 
			
		||||
    void setupActions();
 | 
			
		||||
 | 
			
		||||
    ProjectManager* m_projectManager;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
#endif // MAINWINDOW_H
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										63
									
								
								ui/welcome/recentprojectwidget.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								ui/welcome/recentprojectwidget.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
#include "recentprojectwidget.h"
 | 
			
		||||
#include "ui_recentprojectwidget.h"
 | 
			
		||||
 | 
			
		||||
namespace Ember {
 | 
			
		||||
 | 
			
		||||
RecentProjectWidget::RecentProjectWidget(RecentProject project, QWidget *parent) :
 | 
			
		||||
    QWidget(parent),
 | 
			
		||||
    ui(new Ui::RecentProjectWidget),
 | 
			
		||||
    m_project(project),
 | 
			
		||||
    m_selected(false)
 | 
			
		||||
{
 | 
			
		||||
    ui->setupUi(this);
 | 
			
		||||
    setupActions();
 | 
			
		||||
    setSelected(false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RecentProjectWidget::~RecentProjectWidget()
 | 
			
		||||
{
 | 
			
		||||
    delete ui;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RecentProjectWidget::setupUi()
 | 
			
		||||
{
 | 
			
		||||
    ui->text->setText(QString::fromStdString(m_project.name));
 | 
			
		||||
    ui->buttonPin->setChecked(m_project.pinned);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RecentProjectWidget::setupActions()
 | 
			
		||||
{
 | 
			
		||||
    connect(ui->buttonDelete, &QToolButton::clicked, this, &RecentProjectWidget::onDeleteClicked);
 | 
			
		||||
    connect(ui->buttonPin, &QToolButton::toggled, this, &RecentProjectWidget::onPinToggled);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const RecentProject& RecentProjectWidget::project() const
 | 
			
		||||
{
 | 
			
		||||
    return m_project;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RecentProjectWidget::setSelected(bool selected)
 | 
			
		||||
{
 | 
			
		||||
    m_selected = selected;
 | 
			
		||||
    ui->buttonPin->setVisible(selected);
 | 
			
		||||
    ui->buttonDelete->setVisible(selected);
 | 
			
		||||
    ui->textPin->setVisible(!selected && ui->buttonPin->isChecked());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RecentProjectWidget::onDeleteClicked()
 | 
			
		||||
{
 | 
			
		||||
    emit deleted(m_project);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RecentProjectWidget::onPinToggled(bool pinned)
 | 
			
		||||
{
 | 
			
		||||
    ui->textPin->setVisible(!m_selected && pinned);
 | 
			
		||||
    if (m_project.pinned != pinned)
 | 
			
		||||
    {
 | 
			
		||||
        m_project.pinned = pinned;
 | 
			
		||||
        emit pinToggled(m_project, pinned);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										43
									
								
								ui/welcome/recentprojectwidget.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								ui/welcome/recentprojectwidget.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
#ifndef RECENTPROJECTWIDGET_H
 | 
			
		||||
#define RECENTPROJECTWIDGET_H
 | 
			
		||||
 | 
			
		||||
#include <QWidget>
 | 
			
		||||
#include <model/project.h>
 | 
			
		||||
 | 
			
		||||
namespace Ui {
 | 
			
		||||
class RecentProjectWidget;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Ember {
 | 
			
		||||
 | 
			
		||||
class RecentProjectWidget : public QWidget
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    explicit RecentProjectWidget(RecentProject project, QWidget *parent = 0);
 | 
			
		||||
    virtual ~RecentProjectWidget();
 | 
			
		||||
 | 
			
		||||
    const RecentProject& project() const;
 | 
			
		||||
 | 
			
		||||
    void setSelected(bool selected);
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
    void deleted(const RecentProject& project);
 | 
			
		||||
    void pinToggled(const RecentProject& project, bool pinned);
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
    void onDeleteClicked();
 | 
			
		||||
    void onPinToggled(bool pinned);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    void setupUi();
 | 
			
		||||
    void setupActions();
 | 
			
		||||
 | 
			
		||||
    Ui::RecentProjectWidget *ui;
 | 
			
		||||
    RecentProject m_project;
 | 
			
		||||
    bool m_selected;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
#endif // RECENTPROJECTWIDGET_H
 | 
			
		||||
							
								
								
									
										76
									
								
								ui/welcome/recentprojectwidget.ui
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								ui/welcome/recentprojectwidget.ui
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<ui version="4.0">
 | 
			
		||||
 <class>RecentProjectWidget</class>
 | 
			
		||||
 <widget class="QWidget" name="RecentProjectWidget">
 | 
			
		||||
  <property name="geometry">
 | 
			
		||||
   <rect>
 | 
			
		||||
    <x>0</x>
 | 
			
		||||
    <y>0</y>
 | 
			
		||||
    <width>663</width>
 | 
			
		||||
    <height>46</height>
 | 
			
		||||
   </rect>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="windowTitle">
 | 
			
		||||
   <string>Form</string>
 | 
			
		||||
  </property>
 | 
			
		||||
  <layout class="QHBoxLayout" name="horizontalLayout">
 | 
			
		||||
   <property name="sizeConstraint">
 | 
			
		||||
    <enum>QLayout::SetMinimumSize</enum>
 | 
			
		||||
   </property>
 | 
			
		||||
   <item>
 | 
			
		||||
    <widget class="QLabel" name="text">
 | 
			
		||||
     <property name="sizePolicy">
 | 
			
		||||
      <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
 | 
			
		||||
       <horstretch>1</horstretch>
 | 
			
		||||
       <verstretch>0</verstretch>
 | 
			
		||||
      </sizepolicy>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="text">
 | 
			
		||||
      <string>TextLabel</string>
 | 
			
		||||
     </property>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item>
 | 
			
		||||
    <widget class="QToolButton" name="buttonPin">
 | 
			
		||||
     <property name="font">
 | 
			
		||||
      <font>
 | 
			
		||||
       <family>Font Awesome 5 Free</family>
 | 
			
		||||
      </font>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="text">
 | 
			
		||||
      <string></string>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="checkable">
 | 
			
		||||
      <bool>true</bool>
 | 
			
		||||
     </property>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item>
 | 
			
		||||
    <widget class="QToolButton" name="buttonDelete">
 | 
			
		||||
     <property name="font">
 | 
			
		||||
      <font>
 | 
			
		||||
       <family>Font Awesome 5 Free</family>
 | 
			
		||||
      </font>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="text">
 | 
			
		||||
      <string></string>
 | 
			
		||||
     </property>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
   <item>
 | 
			
		||||
    <widget class="QLabel" name="textPin">
 | 
			
		||||
     <property name="font">
 | 
			
		||||
      <font>
 | 
			
		||||
       <family>Font Awesome 5 Free</family>
 | 
			
		||||
      </font>
 | 
			
		||||
     </property>
 | 
			
		||||
     <property name="text">
 | 
			
		||||
      <string></string>
 | 
			
		||||
     </property>
 | 
			
		||||
    </widget>
 | 
			
		||||
   </item>
 | 
			
		||||
  </layout>
 | 
			
		||||
 </widget>
 | 
			
		||||
 <resources/>
 | 
			
		||||
 <connections/>
 | 
			
		||||
</ui>
 | 
			
		||||
@@ -1,14 +1,157 @@
 | 
			
		||||
#include <QFileDialog>
 | 
			
		||||
 | 
			
		||||
#include <properties/config.h>
 | 
			
		||||
 | 
			
		||||
#include "welcomedialog.h"
 | 
			
		||||
#include "ui_welcomedialog.h"
 | 
			
		||||
#include "recentprojectwidget.h"
 | 
			
		||||
 | 
			
		||||
WelcomeDialog::WelcomeDialog(QWidget *parent) :
 | 
			
		||||
namespace Ember {
 | 
			
		||||
 | 
			
		||||
WelcomeDialog::WelcomeDialog(ProjectManager* projectManager, QWidget *parent) :
 | 
			
		||||
    QDialog(parent),
 | 
			
		||||
    ui(new Ui::WelcomeDialog)
 | 
			
		||||
    ui(new Ui::WelcomeDialog),
 | 
			
		||||
    m_projectManager(projectManager),
 | 
			
		||||
    m_originalPicture()
 | 
			
		||||
{
 | 
			
		||||
    ui->setupUi(this);
 | 
			
		||||
    m_originalPicture = QPixmap(*ui->picture->pixmap());
 | 
			
		||||
    setResult(Rejected);
 | 
			
		||||
 | 
			
		||||
    setupActions();
 | 
			
		||||
    populateProjects();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
WelcomeDialog::~WelcomeDialog()
 | 
			
		||||
{
 | 
			
		||||
    delete ui;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WelcomeDialog::setupActions()
 | 
			
		||||
{
 | 
			
		||||
    connect(ui->buttonNewProject, &QCommandLinkButton::clicked, this, &WelcomeDialog::onNewProjectClicked);
 | 
			
		||||
    connect(ui->buttonOpenProject, &QCommandLinkButton::clicked, this, &WelcomeDialog::onOpenProjectClicked);
 | 
			
		||||
    connect(ui->listRecentProjects, &QListWidget::currentItemChanged, this, &WelcomeDialog::onProjectCurrentChanged);
 | 
			
		||||
    connect(ui->listRecentProjects, &QListWidget::itemActivated, this, &WelcomeDialog::onProjectActivated);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WelcomeDialog::populateProjects()
 | 
			
		||||
{
 | 
			
		||||
    std::vector<RecentProject> projects;
 | 
			
		||||
    for (auto pair : m_projectManager->recentProjects())
 | 
			
		||||
        projects.push_back(pair.second);
 | 
			
		||||
 | 
			
		||||
    // Sort by pinned and access date
 | 
			
		||||
    std::sort(projects.begin(), projects.end(), [](const RecentProject& a, const RecentProject& b) -> bool
 | 
			
		||||
    {
 | 
			
		||||
        if (a.pinned == b.pinned)
 | 
			
		||||
            return a.access > b.access;
 | 
			
		||||
 | 
			
		||||
        return a.pinned > b.pinned;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Add items
 | 
			
		||||
    for (auto& project : projects)
 | 
			
		||||
    {
 | 
			
		||||
        RecentProjectWidget* itemWidget = new RecentProjectWidget(project);
 | 
			
		||||
        connect(itemWidget, &RecentProjectWidget::pinToggled, this, &WelcomeDialog::onProjectPinned);
 | 
			
		||||
        connect(itemWidget, &RecentProjectWidget::deleted, this, &WelcomeDialog::onProjectDeleted);
 | 
			
		||||
 | 
			
		||||
        QListWidgetItem* item = new QListWidgetItem();
 | 
			
		||||
        item->setSizeHint(itemWidget->sizeHint());
 | 
			
		||||
 | 
			
		||||
        ui->listRecentProjects->addItem(item);
 | 
			
		||||
        ui->listRecentProjects->setItemWidget(item, itemWidget);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WelcomeDialog::resizeEvent(QResizeEvent*)
 | 
			
		||||
{
 | 
			
		||||
    QSize pictSize = ui->picture->size();
 | 
			
		||||
    QPixmap pictScaled = m_originalPicture.scaled(pictSize, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
 | 
			
		||||
    ui->picture->setPixmap(pictScaled);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WelcomeDialog::onNewProjectClicked()
 | 
			
		||||
{
 | 
			
		||||
    m_resultAction = NEW_PROJECT;
 | 
			
		||||
    accept();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WelcomeDialog::onOpenProjectClicked()
 | 
			
		||||
{
 | 
			
		||||
    QString path = QFileDialog::getOpenFileName(this, tr("Open project"), "", buildFilterString());
 | 
			
		||||
 | 
			
		||||
    if (!path.isEmpty())
 | 
			
		||||
    {
 | 
			
		||||
        QByteArray str = path.toUtf8();
 | 
			
		||||
        m_openPath.assign(str.begin(), str.end());
 | 
			
		||||
        m_resultAction = OPEN_PROJECT;
 | 
			
		||||
        accept();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WelcomeDialog::onProjectPinned(const RecentProject& project, bool pinned)
 | 
			
		||||
{
 | 
			
		||||
    m_projectManager->pinRecentProject(project.path, pinned);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WelcomeDialog::onProjectDeleted(const RecentProject& project)
 | 
			
		||||
{
 | 
			
		||||
    m_projectManager->deleteRecentProject(project.path);
 | 
			
		||||
    delete ui->listRecentProjects->takeItem(ui->listRecentProjects->currentRow());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WelcomeDialog::onProjectCurrentChanged(QListWidgetItem *current, QListWidgetItem *previous)
 | 
			
		||||
{
 | 
			
		||||
    if (previous)
 | 
			
		||||
    {
 | 
			
		||||
        RecentProjectWidget* itemWidget = (RecentProjectWidget*) ui->listRecentProjects->itemWidget(previous);
 | 
			
		||||
        if (itemWidget)
 | 
			
		||||
            itemWidget->setSelected(false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (current)
 | 
			
		||||
    {
 | 
			
		||||
        RecentProjectWidget* itemWidget = (RecentProjectWidget*) ui->listRecentProjects->itemWidget(current);
 | 
			
		||||
        if (itemWidget)
 | 
			
		||||
            itemWidget->setSelected(true);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void WelcomeDialog::onProjectActivated(QListWidgetItem *item)
 | 
			
		||||
{
 | 
			
		||||
    RecentProjectWidget* itemWidget = (RecentProjectWidget*) ui->listRecentProjects->itemWidget(item);
 | 
			
		||||
    if (itemWidget)
 | 
			
		||||
    {
 | 
			
		||||
        m_resultAction = OPEN_PROJECT;
 | 
			
		||||
        m_openPath = itemWidget->project().path;
 | 
			
		||||
        accept();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString WelcomeDialog::buildFilterString()
 | 
			
		||||
{
 | 
			
		||||
    static QString str;
 | 
			
		||||
    if (str.isEmpty())
 | 
			
		||||
    {
 | 
			
		||||
        str = QString("%1 (*%2);;%3 (*.*)").arg(
 | 
			
		||||
            tr("Project files"),
 | 
			
		||||
            EMBER_PROJECT_EXTENSION,
 | 
			
		||||
            tr("All files"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
boost::filesystem::path WelcomeDialog::openPath() const
 | 
			
		||||
{
 | 
			
		||||
    return m_openPath;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
WelcomeDialog::ResultAction WelcomeDialog::resultAction() const
 | 
			
		||||
{
 | 
			
		||||
    return m_resultAction;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,21 +2,54 @@
 | 
			
		||||
#define WELCOMEDIALOG_H
 | 
			
		||||
 | 
			
		||||
#include <QDialog>
 | 
			
		||||
#include <QListWidget>
 | 
			
		||||
#include <business/projectmanager.h>
 | 
			
		||||
 | 
			
		||||
namespace Ui {
 | 
			
		||||
class WelcomeDialog;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Ember {
 | 
			
		||||
 | 
			
		||||
class WelcomeDialog : public QDialog
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    explicit WelcomeDialog(QWidget *parent = 0);
 | 
			
		||||
    ~WelcomeDialog();
 | 
			
		||||
    enum ResultAction
 | 
			
		||||
    {
 | 
			
		||||
        NEW_PROJECT,
 | 
			
		||||
        OPEN_PROJECT
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    explicit WelcomeDialog(ProjectManager* projectManager, QWidget *parent = 0);
 | 
			
		||||
    virtual ~WelcomeDialog();
 | 
			
		||||
 | 
			
		||||
    ResultAction resultAction() const;
 | 
			
		||||
    boost::filesystem::path openPath() const;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    virtual void resizeEvent(QResizeEvent*) override;
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
    void onNewProjectClicked();
 | 
			
		||||
    void onOpenProjectClicked();
 | 
			
		||||
    void onProjectPinned(const RecentProject& project, bool pinned);
 | 
			
		||||
    void onProjectDeleted(const RecentProject& project);
 | 
			
		||||
    void onProjectCurrentChanged(QListWidgetItem* current, QListWidgetItem* previous);
 | 
			
		||||
    void onProjectActivated(QListWidgetItem* item);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    void setupActions();
 | 
			
		||||
    void populateProjects();
 | 
			
		||||
    static QString buildFilterString();
 | 
			
		||||
 | 
			
		||||
    Ui::WelcomeDialog *ui;
 | 
			
		||||
    ProjectManager* m_projectManager;
 | 
			
		||||
    QPixmap m_originalPicture;
 | 
			
		||||
    ResultAction m_resultAction;
 | 
			
		||||
    boost::filesystem::path m_openPath;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
#endif // WELCOMEDIALOG_H
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user