mirror of
https://gitlab.com/samplehive/sample-hive.git
synced 2026-10-11 07:24:12 +02:00
Initial commit
This commit is contained in:
+41
@@ -0,0 +1,41 @@
|
||||
#include "App.hpp"
|
||||
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/splash.h>
|
||||
|
||||
wxIMPLEMENT_APP(App);
|
||||
|
||||
App::App()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
App::~App()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool App::OnInit()
|
||||
{
|
||||
if (!wxApp::OnInit())
|
||||
return false;
|
||||
|
||||
m_Frame = new MainFrame();
|
||||
|
||||
wxBitmap bitmap;
|
||||
wxSplashScreen* splash;
|
||||
|
||||
if (bitmap.LoadFile("../assets/Logo/logo-hive_768x432.png", wxBITMAP_TYPE_PNG))
|
||||
{
|
||||
splash = new wxSplashScreen(bitmap,
|
||||
wxSPLASH_CENTRE_ON_SCREEN | wxSPLASH_TIMEOUT,
|
||||
2000, NULL, -1, wxDefaultPosition, wxDefaultSize,
|
||||
wxBORDER_SIMPLE | wxSTAY_ON_TOP);
|
||||
}
|
||||
|
||||
wxYield();
|
||||
|
||||
m_Frame->Show(true);
|
||||
return true;
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <wx/app.h>
|
||||
|
||||
#include "MainFrame.hpp"
|
||||
|
||||
class App : public wxApp
|
||||
{
|
||||
public:
|
||||
App();
|
||||
~App();
|
||||
|
||||
private:
|
||||
MainFrame* m_Frame = nullptr;
|
||||
|
||||
public:
|
||||
virtual bool OnInit();
|
||||
};
|
||||
+1068
File diff suppressed because it is too large
Load Diff
+182
@@ -0,0 +1,182 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <wx/button.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/collpane.h>
|
||||
#include <wx/dataview.h>
|
||||
#include <wx/dirctrl.h>
|
||||
#include <wx/dirdlg.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/infobar.h>
|
||||
#include <wx/listctrl.h>
|
||||
#include <wx/mediactrl.h>
|
||||
#include <wx/notebook.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/setup.h>
|
||||
#include <wx/srchctrl.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/slider.h>
|
||||
#include <wx/splitter.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/stringimpl.h>
|
||||
#include <wx/tglbtn.h>
|
||||
#include <wx/timer.h>
|
||||
#include <wx/toplevel.h>
|
||||
#include <wx/treebase.h>
|
||||
#include <wx/treectrl.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
#include <wxSVG/svgctrl.h>
|
||||
#include <wxSVG/SVGDocument.h>
|
||||
|
||||
#include <taglib/taglib.h>
|
||||
#include <taglib/fileref.h>
|
||||
#include <taglib/tstring.h>
|
||||
|
||||
#include "Database.hpp"
|
||||
#include "Serialize.hpp"
|
||||
|
||||
class Browser : public wxPanel
|
||||
{
|
||||
public:
|
||||
Browser(wxWindow* window);
|
||||
~Browser();
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
// Splitter windows
|
||||
wxSplitterWindow* m_TopSplitter;
|
||||
wxSplitterWindow* m_BottomSplitter;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Top panel controls
|
||||
wxPanel* m_TopPanel;
|
||||
wxBoxSizer* m_TopSizer;
|
||||
wxBoxSizer* m_TopPanelMainSizer;
|
||||
wxBoxSizer* m_WaveformDisplaySizer;
|
||||
wxSVGCtrl* m_WaveformViewer;
|
||||
wxBoxSizer* m_BrowserControlSizer;
|
||||
wxButton* m_PlayButton;
|
||||
wxToggleButton* m_LoopButton;
|
||||
wxButton* m_StopButton;
|
||||
wxButton* m_SettingsButton;
|
||||
wxToggleButton* m_MuteButton;
|
||||
wxStaticText* m_SamplePosition;
|
||||
wxSlider* m_VolumeSlider;
|
||||
wxCheckBox* m_AutoPlayCheck;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Left panel controls
|
||||
wxPanel* m_BottomLeftPanel;
|
||||
wxPanel* m_CollectionViewPanel;
|
||||
wxWindow* m_TrashPaneWindow;
|
||||
wxNotebook* m_ViewChoice;
|
||||
wxBoxSizer* m_BottomLeftPanelMainSizer;
|
||||
wxBoxSizer* m_CollectionViewMainSizer;
|
||||
wxBoxSizer* m_CollectionViewFavoritesSizer;
|
||||
wxBoxSizer* m_CollectionViewTrashSizer;
|
||||
wxBoxSizer* m_CollectionViewButtonSizer;
|
||||
wxBoxSizer* m_TrashItemSizer;
|
||||
wxSizerItem *m_CollectionViewTrashSizerItem;
|
||||
wxDirCtrl* m_DirCtrl;
|
||||
wxTreeCtrl* m_CollectionView;
|
||||
wxTreeItemId rootNode;
|
||||
wxTreeItemId trash_root_node;
|
||||
wxCollapsiblePane* m_TrashPane;
|
||||
wxTreeCtrl* m_TrashedItems;
|
||||
wxButton* m_AddTreeItemButton;
|
||||
wxButton* m_RemoveTreeItemButton;
|
||||
wxButton* m_TrashButton;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Right panel controls
|
||||
wxPanel* m_BottomRightPanel;
|
||||
wxBoxSizer* m_BottomRightPanelMainSizer;
|
||||
wxBoxSizer* m_SearchBoxSizer;
|
||||
wxBoxSizer* m_ListCtrlSizer;
|
||||
wxSearchCtrl* m_SearchBox;
|
||||
wxInfoBar* m_InfoBar;
|
||||
wxDataViewListCtrl* m_SampleListView;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// MediaCtrl
|
||||
wxMediaCtrl* m_MediaCtrl;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Timer
|
||||
wxTimer* m_Timer;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
bool bAutoplay = false;
|
||||
bool bLoop = false;
|
||||
bool bMuted = false;
|
||||
bool bStopped = false;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
std::string configFilepath;
|
||||
std::string databaseFilepath;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
Serializer serialize;
|
||||
Database db;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
// Top panel control handlers
|
||||
void OnClickPlay(wxCommandEvent& event);
|
||||
void OnClickLoop(wxCommandEvent& event);
|
||||
void OnClickStop(wxCommandEvent& event);
|
||||
void OnClickMute(wxCommandEvent& event);
|
||||
void OnMediaFinished(wxMediaEvent& event);
|
||||
void OnCheckAutoplay(wxCommandEvent& event);
|
||||
void OnSlideVolume(wxScrollEvent& event);
|
||||
void OnClickSettings(wxCommandEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// DirCtrl event handlers
|
||||
void OnClickDirCtrl(wxCommandEvent& event);
|
||||
void OnDragFromDirCtrl(wxTreeEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// TrashPane event handlers
|
||||
void OnExpandTrash(wxCollapsiblePaneEvent& event);
|
||||
void OnClickTrash(wxCommandEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// CollectionViewPanel button event handlers
|
||||
// void OnClickCollectionView(wxTreeEvent& event);
|
||||
void OnClickCollectionAdd(wxCommandEvent& event);
|
||||
void OnClickCollectionRemove(wxCommandEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// SearchCtrl event handlers
|
||||
void OnDoSearch(wxCommandEvent& event);
|
||||
void OnCancelSearch(wxCommandEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// SampleListView event handlers
|
||||
void OnCheckFavorite(wxDataViewEvent& event);
|
||||
void OnClickSampleView(wxDataViewEvent& event);
|
||||
void OnDragAndDropToSampleListView(wxDropFilesEvent& event);
|
||||
void OnDragFromSampleView(wxDataViewEvent& event);
|
||||
void OnShowSampleListViewContextMenu(wxDataViewEvent& event);
|
||||
void OnSampleListViewContextMenuSelect(wxCommandEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Timer update event handler
|
||||
void UpdateElapsedTime(wxTimerEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void AddSamples(wxString file);
|
||||
void OnAutoImportDir();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void RestoreDatabase();
|
||||
void LoadConfigFile();
|
||||
|
||||
// wxString TagLibTowx(const TagLib::String& in);
|
||||
};
|
||||
@@ -0,0 +1,58 @@
|
||||
#include <wx/defs.h>
|
||||
|
||||
enum ControlIDs
|
||||
{
|
||||
/*
|
||||
** BC = Browser control
|
||||
** SD = Settings dialog
|
||||
** MN = Popup menu
|
||||
** ET = Edit tag dialog
|
||||
*/
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Browser controls
|
||||
BC_Play = wxID_HIGHEST + 1,
|
||||
BC_Settings,
|
||||
BC_Loop,
|
||||
BC_Stop,
|
||||
BC_Mute,
|
||||
BC_Autoplay,
|
||||
BC_Volume,
|
||||
BC_SamplePosition,
|
||||
BC_CollectionView,
|
||||
BC_DirCtrl,
|
||||
BC_SampleListView,
|
||||
BC_Search,
|
||||
BC_MediaCtrl,
|
||||
BC_TrashPane,
|
||||
BC_TrashButton,
|
||||
BC_CollectionViewAdd,
|
||||
BC_CollectionViewRemove,
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Setting dialog controls
|
||||
SD_BrowseConfigDir,
|
||||
SD_BrowseDatabaseDir,
|
||||
SD_AutoImport,
|
||||
SD_BrowseAutoImportDir,
|
||||
SD_FontType,
|
||||
SD_FontSize,
|
||||
SD_FontBrowseButton,
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Menu items
|
||||
MN_FavoriteSample,
|
||||
MN_DeleteSample,
|
||||
MN_TrashSample,
|
||||
MN_EditTagSample,
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Edit tags dialog controls
|
||||
ET_TitleCheck,
|
||||
ET_ArtistCheck,
|
||||
ET_AlbumCheck,
|
||||
ET_GenreCheck,
|
||||
ET_CommentsCheck,
|
||||
ET_TypeCheck,
|
||||
ET_CustomTag,
|
||||
};
|
||||
@@ -0,0 +1,710 @@
|
||||
#include <exception>
|
||||
|
||||
#include <wx/log.h>
|
||||
#include <wx/msgdlg.h>
|
||||
#include <wx/string.h>
|
||||
|
||||
#include "Database.hpp"
|
||||
|
||||
Database::Database(wxInfoBar& infoBar)
|
||||
: m_InfoBar(infoBar)
|
||||
{
|
||||
/* Create SQL statement */
|
||||
std::string sample = "CREATE TABLE IF NOT EXISTS SAMPLES("
|
||||
"FAVORITE INT NOT NULL,"
|
||||
"FILENAME TEXT NOT NULL,"
|
||||
"SAMPLEPACK TEXT NOT NULL,"
|
||||
"TYPE TEXT NOT NULL,"
|
||||
"CHANNELS INT NOT NULL,"
|
||||
"LENGTH INT NOT NULL,"
|
||||
"SAMPLERATE INT NOT NULL,"
|
||||
"BITRATE INT NOT NULL,"
|
||||
"PATH TEXT NOT NULL,"
|
||||
"TRASHED INT NOT NULL);";
|
||||
|
||||
try
|
||||
{
|
||||
rc = sqlite3_open("Samples.db", &m_Database);
|
||||
rc = sqlite3_exec(m_Database, sample.c_str(), NULL, 0, &m_ErrMsg);
|
||||
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
wxMessageDialog* msgDialog = new wxMessageDialog(NULL, "Error! Cannot create table.", "Error", wxOK | wxICON_ERROR);
|
||||
msgDialog->ShowModal();
|
||||
sqlite3_free(m_ErrMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogDebug("Table created successfully.");
|
||||
}
|
||||
|
||||
sqlite3_close(m_Database);
|
||||
}
|
||||
catch (const std::exception &exception)
|
||||
{
|
||||
wxLogDebug(exception.what());
|
||||
}
|
||||
}
|
||||
|
||||
Database::~Database()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Database::InsertSample(int favorite, std::string filename,
|
||||
std::string samplePack, std::string type,
|
||||
int channels, int length, int sampleRate,
|
||||
int bitrate, std::string path, int trashed)
|
||||
{
|
||||
try
|
||||
{
|
||||
rc = sqlite3_open("Samples.db", &m_Database);
|
||||
|
||||
std::string insert = "INSERT INTO SAMPLES (FAVORITE, FILENAME, \
|
||||
SAMPLEPACK, TYPE, CHANNELS, LENGTH, SAMPLERATE, \
|
||||
BITRATE, PATH, TRASHED) \
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);";
|
||||
|
||||
rc = sqlite3_prepare_v2(m_Database, insert.c_str(), insert.size(), &m_Stmt, NULL);
|
||||
|
||||
rc = sqlite3_bind_int(m_Stmt, 1, favorite);
|
||||
rc = sqlite3_bind_text(m_Stmt, 2, filename.c_str(), filename.size(), SQLITE_STATIC);
|
||||
rc = sqlite3_bind_text(m_Stmt, 3, samplePack.c_str(), samplePack.size(), SQLITE_STATIC);
|
||||
rc = sqlite3_bind_text(m_Stmt, 4, type.c_str(), type.size(), SQLITE_STATIC);
|
||||
rc = sqlite3_bind_int(m_Stmt, 5, channels);
|
||||
rc = sqlite3_bind_int(m_Stmt, 6, length);
|
||||
rc = sqlite3_bind_int(m_Stmt, 7, sampleRate);
|
||||
rc = sqlite3_bind_int(m_Stmt, 8, bitrate);
|
||||
rc = sqlite3_bind_text(m_Stmt, 9, path.c_str(), path.size(), SQLITE_STATIC);
|
||||
rc = sqlite3_bind_int(m_Stmt, 10, trashed);
|
||||
|
||||
if (sqlite3_step(m_Stmt) != SQLITE_DONE)
|
||||
{
|
||||
wxLogWarning("No data inserted.");
|
||||
}
|
||||
|
||||
rc = sqlite3_finalize(m_Stmt);
|
||||
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
wxMessageDialog* msgDialog;
|
||||
msgDialog = new wxMessageDialog(NULL,
|
||||
"Error! Cannot insert data into table.",
|
||||
"Error", wxOK | wxICON_ERROR);
|
||||
// msgDialog->ShowModal();
|
||||
sqlite3_free(m_ErrMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogInfo("Data inserted successfully. %s", m_ErrMsg);
|
||||
}
|
||||
|
||||
sqlite3_close(m_Database);
|
||||
}
|
||||
catch (const std::exception &exception)
|
||||
{
|
||||
wxLogDebug(exception.what());
|
||||
}
|
||||
}
|
||||
|
||||
void Database::UpdateFolder(std::string folderName)
|
||||
{
|
||||
try
|
||||
{
|
||||
rc = sqlite3_open("Samples.db", &m_Database);
|
||||
|
||||
std::string update = "UPDATE SAMPLES SET FOLDER = ?;";
|
||||
|
||||
rc = sqlite3_prepare_v2(m_Database, update.c_str(), update.size(), &m_Stmt, NULL);
|
||||
|
||||
rc = sqlite3_bind_text(m_Stmt, 1, folderName.c_str(), folderName.size(), SQLITE_STATIC);
|
||||
|
||||
if (sqlite3_step(m_Stmt) != SQLITE_DONE)
|
||||
{
|
||||
wxLogWarning("No data inserted.");
|
||||
}
|
||||
|
||||
rc = sqlite3_finalize(m_Stmt);
|
||||
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
wxMessageDialog* msgDialog = new wxMessageDialog(NULL, "Error! Cannot insert folder into table.", "Error", wxOK | wxICON_ERROR);
|
||||
msgDialog->ShowModal();
|
||||
sqlite3_free(m_ErrMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogInfo("Folder inserted successfully. %s", m_ErrMsg);
|
||||
}
|
||||
|
||||
sqlite3_close(m_Database);
|
||||
}
|
||||
catch (const std::exception &exception)
|
||||
{
|
||||
wxLogDebug(exception.what());
|
||||
}
|
||||
}
|
||||
|
||||
void Database::UpdateFavoriteFolderDatabase(std::string filename, std::string folderName)
|
||||
{
|
||||
try
|
||||
{
|
||||
rc = sqlite3_open("Samples.db", &m_Database);
|
||||
|
||||
std::string update = "UPDATE SAMPLES SET FAVORITEFOLDER = ? WHERE FILENAME = ?;";
|
||||
|
||||
rc = sqlite3_prepare_v2(m_Database, update.c_str(), update.size(), &m_Stmt, NULL);
|
||||
|
||||
rc = sqlite3_bind_text(m_Stmt, 1, folderName.c_str(), folderName.size(), SQLITE_STATIC);
|
||||
rc = sqlite3_bind_text(m_Stmt, 2, filename.c_str(), filename.size(), SQLITE_STATIC);
|
||||
|
||||
if (sqlite3_step(m_Stmt) == SQLITE_ROW)
|
||||
{
|
||||
wxLogDebug("Record found, updating..");
|
||||
}
|
||||
|
||||
rc = sqlite3_finalize(m_Stmt);
|
||||
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
wxMessageDialog* msgDialog = new wxMessageDialog(NULL, "Error! Cannot update record.", "Error", wxOK | wxICON_ERROR);
|
||||
msgDialog->ShowModal();
|
||||
sqlite3_free(m_ErrMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogDebug("Updated record successfully.");
|
||||
}
|
||||
|
||||
sqlite3_close(m_Database);
|
||||
}
|
||||
catch (const std::exception &exception)
|
||||
{
|
||||
wxLogDebug(exception.what());
|
||||
}
|
||||
}
|
||||
|
||||
void Database::UpdateFavoriteColumn(std::string filename, int value)
|
||||
{
|
||||
try
|
||||
{
|
||||
rc = sqlite3_open("Samples.db", &m_Database);
|
||||
|
||||
std::string update = "UPDATE SAMPLES SET FAVORITE = ? WHERE FILENAME = ?;";
|
||||
|
||||
rc = sqlite3_prepare_v2(m_Database, update.c_str(), update.size(), &m_Stmt, NULL);
|
||||
|
||||
rc = sqlite3_bind_int(m_Stmt, 1, value);
|
||||
rc = sqlite3_bind_text(m_Stmt, 2, filename.c_str(), filename.size(), SQLITE_STATIC);
|
||||
|
||||
if (sqlite3_step(m_Stmt) == SQLITE_ROW)
|
||||
{
|
||||
wxLogDebug("Record found, updating..");
|
||||
}
|
||||
|
||||
rc = sqlite3_finalize(m_Stmt);
|
||||
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
wxMessageDialog* msgDialog = new wxMessageDialog(NULL, "Error! Cannot update record.", "Error", wxOK | wxICON_ERROR);
|
||||
msgDialog->ShowModal();
|
||||
sqlite3_free(m_ErrMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogDebug("Updated record successfully.");
|
||||
}
|
||||
|
||||
sqlite3_close(m_Database);
|
||||
}
|
||||
catch (const std::exception &exception)
|
||||
{
|
||||
wxLogDebug(exception.what());
|
||||
}
|
||||
}
|
||||
|
||||
void Database::UpdateSampleType(std::string filename, std::string type)
|
||||
{
|
||||
try
|
||||
{
|
||||
rc = sqlite3_open("Samples.db", &m_Database);
|
||||
|
||||
std::string update = "UPDATE SAMPLES SET TYPE = ? WHERE FILENAME = ?;";
|
||||
|
||||
rc = sqlite3_prepare_v2(m_Database, update.c_str(), update.size(), &m_Stmt, NULL);
|
||||
|
||||
rc = sqlite3_bind_text(m_Stmt, 1, type.c_str(), type.size(), SQLITE_STATIC);
|
||||
rc = sqlite3_bind_text(m_Stmt, 2, filename.c_str(), filename.size(), SQLITE_STATIC);
|
||||
|
||||
if (sqlite3_step(m_Stmt) == SQLITE_ROW)
|
||||
{
|
||||
wxLogDebug("Record found, updating..");
|
||||
}
|
||||
|
||||
rc = sqlite3_finalize(m_Stmt);
|
||||
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
wxMessageDialog* msgDialog = new wxMessageDialog(NULL, "Error! Cannot update record.", "Error", wxOK | wxICON_ERROR);
|
||||
msgDialog->ShowModal();
|
||||
sqlite3_free(m_ErrMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogDebug("Updated record successfully.");
|
||||
}
|
||||
|
||||
sqlite3_close(m_Database);
|
||||
}
|
||||
catch (const std::exception &exception)
|
||||
{
|
||||
wxLogDebug(exception.what());
|
||||
}
|
||||
}
|
||||
|
||||
std::string Database::GetSampleType(std::string filename)
|
||||
{
|
||||
std::string type;
|
||||
|
||||
try
|
||||
{
|
||||
rc = sqlite3_open("Samples.db", &m_Database);
|
||||
|
||||
std::string select = "SELECT TYPE FROM SAMPLES WHERE FILENAME = ?;";
|
||||
|
||||
rc = sqlite3_prepare_v2(m_Database, select.c_str(), select.size(), &m_Stmt, NULL);
|
||||
|
||||
rc = sqlite3_bind_text(m_Stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC);
|
||||
|
||||
if (sqlite3_step(m_Stmt) == SQLITE_ROW)
|
||||
{
|
||||
wxLogInfo("Record found, fetching..");
|
||||
type = std::string(reinterpret_cast< const char* >(sqlite3_column_text(m_Stmt, 0)));
|
||||
}
|
||||
|
||||
rc = sqlite3_finalize(m_Stmt);
|
||||
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
wxMessageDialog* msgDialog = new wxMessageDialog(NULL, "Error! Cannot get favorite column value from table.", "Error", wxOK | wxICON_ERROR);
|
||||
msgDialog->ShowModal();
|
||||
sqlite3_free(m_ErrMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogInfo("Selected data from table successfully.");
|
||||
}
|
||||
|
||||
sqlite3_close(m_Database);
|
||||
}
|
||||
catch (const std::exception &exception)
|
||||
{
|
||||
wxLogDebug(exception.what());
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
int Database::GetFavoriteColumnValueByFilename(std::string filename)
|
||||
{
|
||||
int value = 0;
|
||||
|
||||
try
|
||||
{
|
||||
rc = sqlite3_open("Samples.db", &m_Database);
|
||||
|
||||
std::string select = "SELECT FAVORITE FROM SAMPLES WHERE FILENAME = ?;";
|
||||
|
||||
rc = sqlite3_prepare_v2(m_Database, select.c_str(), select.size(), &m_Stmt, NULL);
|
||||
|
||||
rc = sqlite3_bind_text(m_Stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC);
|
||||
|
||||
if (sqlite3_step(m_Stmt) == SQLITE_ROW)
|
||||
{
|
||||
wxLogInfo("Record found, fetching..");
|
||||
value = sqlite3_column_int(m_Stmt, 0);
|
||||
}
|
||||
|
||||
rc = sqlite3_finalize(m_Stmt);
|
||||
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
wxMessageDialog* msgDialog = new wxMessageDialog(NULL, "Error! Cannot get favorite column value from table.", "Error", wxOK | wxICON_ERROR);
|
||||
msgDialog->ShowModal();
|
||||
sqlite3_free(m_ErrMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogInfo("Selected data from table successfully.");
|
||||
}
|
||||
|
||||
sqlite3_close(m_Database);
|
||||
}
|
||||
catch (const std::exception &exception)
|
||||
{
|
||||
wxLogDebug(exception.what());
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void Database::RemoveSampleFromDatabase(std::string filename)
|
||||
{
|
||||
try
|
||||
{
|
||||
rc = sqlite3_open("Samples.db", &m_Database);
|
||||
|
||||
std::string remove = "DELETE * FROM SAMPLES WHERE FILENAME = ?;";
|
||||
|
||||
rc = sqlite3_prepare_v2(m_Database, remove.c_str(), remove.size(), &m_Stmt, NULL);
|
||||
|
||||
rc = sqlite3_bind_text(m_Stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC);
|
||||
|
||||
if (sqlite3_step(m_Stmt) == SQLITE_DONE)
|
||||
{
|
||||
wxLogDebug("Record found, Deleting..");
|
||||
}
|
||||
|
||||
rc = sqlite3_finalize(m_Stmt);
|
||||
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
wxMessageDialog* msgDialog = new wxMessageDialog(NULL, "Error! Cannot delete data from table.", "Error", wxOK | wxICON_ERROR);
|
||||
msgDialog->ShowModal();
|
||||
sqlite3_free(m_ErrMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogDebug("Deleted data from table successfully.");
|
||||
}
|
||||
|
||||
sqlite3_close(m_Database);
|
||||
}
|
||||
catch (const std::exception &exception)
|
||||
{
|
||||
wxLogDebug(exception.what());
|
||||
}
|
||||
}
|
||||
|
||||
std::string Database::GetSamplePathByFilename(std::string filename)
|
||||
{
|
||||
std::string path;
|
||||
|
||||
try
|
||||
{
|
||||
rc = sqlite3_open("Samples.db", &m_Database);
|
||||
|
||||
std::string select = "SELECT PATH FROM SAMPLES WHERE FILENAME = ?;";
|
||||
|
||||
rc = sqlite3_prepare_v2(m_Database, select.c_str(), select.size(), &m_Stmt, NULL);
|
||||
|
||||
rc = sqlite3_bind_text(m_Stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC);
|
||||
|
||||
if (sqlite3_step(m_Stmt) == SQLITE_ROW)
|
||||
{
|
||||
wxLogInfo("Record found, fetching..");
|
||||
path = std::string(reinterpret_cast< const char* >(sqlite3_column_text(m_Stmt, 0)));
|
||||
}
|
||||
|
||||
rc = sqlite3_finalize(m_Stmt);
|
||||
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
wxMessageDialog* msgDialog = new wxMessageDialog(NULL, "Error! Cannot select sample path from table.", "Error", wxOK | wxICON_ERROR);
|
||||
msgDialog->ShowModal();
|
||||
sqlite3_free(m_ErrMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogInfo("Selected data from table successfully.");
|
||||
}
|
||||
|
||||
sqlite3_close(m_Database);
|
||||
}
|
||||
catch (const std::exception &exception)
|
||||
{
|
||||
wxLogDebug(exception.what());
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
wxVector<wxVector<wxVariant>> Database::LoadDatabase(wxVector<wxVector<wxVariant>>& vecSet, wxTreeCtrl& favorite_tree, wxTreeItemId& favorite_item, wxTreeCtrl& trash_tree, wxTreeItemId& trash_item)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (sqlite3_open("Samples.db", &m_Database) != SQLITE_OK)
|
||||
{
|
||||
wxLogDebug("Error opening DB");
|
||||
throw sqlite3_errmsg(m_Database);
|
||||
}
|
||||
|
||||
std::string load = "SELECT FAVORITE, FILENAME, SAMPLEPACK, TYPE, \
|
||||
CHANNELS, LENGTH, SAMPLERATE, BITRATE, TRASHED \
|
||||
FROM SAMPLES;";
|
||||
|
||||
rc = sqlite3_prepare_v2(m_Database, load.c_str(), load.size(), &m_Stmt, NULL);
|
||||
|
||||
if (rc == SQLITE_OK)
|
||||
{
|
||||
int row = 0;
|
||||
|
||||
while (SQLITE_ROW == sqlite3_step(m_Stmt))
|
||||
{
|
||||
wxLogDebug("Record found, fetching..");
|
||||
|
||||
int favorite = sqlite3_column_int(m_Stmt, 0);
|
||||
wxString filename = wxString(std::string(reinterpret_cast< const char* >(sqlite3_column_text(m_Stmt, 1))));
|
||||
wxString sample_pack = wxString(std::string(reinterpret_cast< const char* >(sqlite3_column_text(m_Stmt, 2))));
|
||||
wxString sample_type = std::string(reinterpret_cast<const char *>(sqlite3_column_text(m_Stmt, 3)));
|
||||
int channels = sqlite3_column_int(m_Stmt, 4);
|
||||
int length = sqlite3_column_int(m_Stmt, 5);
|
||||
int sample_rate = sqlite3_column_int(m_Stmt, 6);
|
||||
int bitrate = sqlite3_column_int(m_Stmt, 7);
|
||||
int trashed = sqlite3_column_int(m_Stmt, 8);
|
||||
|
||||
wxVector<wxVariant> vec;
|
||||
|
||||
if (trashed == 1)
|
||||
trash_tree.AppendItem(trash_item, filename);
|
||||
else
|
||||
{
|
||||
if (favorite == 1)
|
||||
{
|
||||
vec.push_back(true);
|
||||
|
||||
favorite_tree.AppendItem(favorite_item, filename);
|
||||
}
|
||||
else
|
||||
vec.push_back(false);
|
||||
|
||||
vec.push_back(filename);
|
||||
vec.push_back(sample_pack);
|
||||
vec.push_back(sample_type);
|
||||
vec.push_back(wxString::Format("%d", channels));
|
||||
vec.push_back(wxString::Format("%d", length));
|
||||
vec.push_back(wxString::Format("%d", sample_rate));
|
||||
vec.push_back(wxString::Format("%d", bitrate));
|
||||
|
||||
vecSet.push_back(vec);
|
||||
}
|
||||
|
||||
row++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wxMessageDialog* msgDialog = new wxMessageDialog(NULL, "Error! Cannot load data from table.", "Error", wxOK | wxICON_ERROR);
|
||||
msgDialog->ShowModal();
|
||||
sqlite3_free(m_ErrMsg);
|
||||
}
|
||||
|
||||
rc = sqlite3_finalize(m_Stmt);
|
||||
|
||||
sqlite3_close(m_Database);
|
||||
}
|
||||
catch (const std::exception &exception)
|
||||
{
|
||||
wxLogDebug(exception.what());
|
||||
}
|
||||
|
||||
return vecSet;
|
||||
}
|
||||
|
||||
wxVector<wxVector<wxVariant>> Database::FilterDatabaseBySampleName(wxVector<wxVector<wxVariant>>& sampleVec, std::string sampleName)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (sqlite3_open("Samples.db", &m_Database) != SQLITE_OK)
|
||||
{
|
||||
wxLogDebug("Error opening DB");
|
||||
throw sqlite3_errmsg(m_Database);
|
||||
}
|
||||
|
||||
std::string filter = "SELECT FAVORITE, FILENAME, SAMPLEPACK, TYPE, \
|
||||
CHANNELS, LENGTH, SAMPLERATE, BITRATE \
|
||||
FROM SAMPLES WHERE FILENAME LIKE '%' || ? || '%';";
|
||||
|
||||
rc = sqlite3_prepare_v2(m_Database, filter.c_str(), filter.size(), &m_Stmt, NULL);
|
||||
|
||||
rc = sqlite3_bind_text(m_Stmt, 1, sampleName.c_str(), sampleName.size(), SQLITE_STATIC);
|
||||
|
||||
if (rc == SQLITE_OK)
|
||||
{
|
||||
int row = 0;
|
||||
|
||||
while (SQLITE_ROW == sqlite3_step(m_Stmt))
|
||||
{
|
||||
wxLogInfo("Record found, fetching..");
|
||||
int favorite = sqlite3_column_int(m_Stmt, 0);
|
||||
wxString filename = wxString(std::string(reinterpret_cast< const char* >(sqlite3_column_text(m_Stmt, 1))));
|
||||
wxString sample_pack = wxString(std::string(reinterpret_cast< const char* >(sqlite3_column_text(m_Stmt, 2))));
|
||||
wxString sample_type = std::string(reinterpret_cast<const char *>(sqlite3_column_text(m_Stmt, 3)));
|
||||
int channels = sqlite3_column_int(m_Stmt, 4);
|
||||
int length = sqlite3_column_int(m_Stmt, 5);
|
||||
int sample_rate = sqlite3_column_int(m_Stmt, 6);
|
||||
int bitrate = sqlite3_column_int(m_Stmt, 7);
|
||||
|
||||
wxVector<wxVariant> vec;
|
||||
|
||||
if (favorite == 1)
|
||||
vec.push_back(true);
|
||||
else
|
||||
vec.push_back(false);
|
||||
|
||||
vec.push_back(filename);
|
||||
vec.push_back(sample_pack);
|
||||
vec.push_back(sample_type);
|
||||
vec.push_back(wxString::Format("%d", channels));
|
||||
vec.push_back(wxString::Format("%d", length));
|
||||
vec.push_back(wxString::Format("%d", sample_rate));
|
||||
vec.push_back(wxString::Format("%d", bitrate));
|
||||
|
||||
sampleVec.push_back(vec);
|
||||
|
||||
row++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wxMessageDialog* msgDialog = new wxMessageDialog(NULL, "Error! Cannot filter data from table.", "Error", wxOK | wxICON_ERROR);
|
||||
msgDialog->ShowModal();
|
||||
sqlite3_free(m_ErrMsg);
|
||||
}
|
||||
|
||||
rc = sqlite3_finalize(m_Stmt);
|
||||
|
||||
sqlite3_close(m_Database);
|
||||
}
|
||||
catch (const std::exception &exception)
|
||||
{
|
||||
wxLogDebug(exception.what());
|
||||
}
|
||||
|
||||
return sampleVec;
|
||||
}
|
||||
|
||||
bool Database::HasSample(std::string filename)
|
||||
{
|
||||
std::string sample;
|
||||
try
|
||||
{
|
||||
rc = sqlite3_open("Samples.db", &m_Database);
|
||||
|
||||
std::string select = "SELECT * FROM SAMPLES WHERE FILENAME = ?;";
|
||||
|
||||
rc = sqlite3_prepare_v2(m_Database, select.c_str(), select.size(), &m_Stmt, NULL);
|
||||
|
||||
rc = sqlite3_bind_text(m_Stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC);
|
||||
|
||||
if (sqlite3_step(m_Stmt) == SQLITE_ROW)
|
||||
{
|
||||
wxLogInfo("Record found, fetching..");
|
||||
sample = std::string(reinterpret_cast< const char* >(sqlite3_column_text(m_Stmt, 0)));
|
||||
return true;
|
||||
}
|
||||
|
||||
rc = sqlite3_finalize(m_Stmt);
|
||||
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
wxMessageDialog* msgDialog = new wxMessageDialog(NULL, "Error! Cannot find data in table.", "Error", wxOK | wxICON_ERROR);
|
||||
msgDialog->ShowModal();
|
||||
sqlite3_free(m_ErrMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogInfo("Selected data from table successfully.");
|
||||
}
|
||||
|
||||
sqlite3_close(m_Database);
|
||||
}
|
||||
catch (const std::exception &exception)
|
||||
{
|
||||
wxLogDebug(exception.what());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Database::IsTrashed(std::string filename)
|
||||
{
|
||||
try
|
||||
{
|
||||
rc = sqlite3_open("Samples.db", &m_Database);
|
||||
|
||||
std::string select = "SELECT TRASHED FROM SAMPLES WHERE FILENAME = ?;";
|
||||
|
||||
rc = sqlite3_prepare_v2(m_Database, select.c_str(), select.size(), &m_Stmt, NULL);
|
||||
|
||||
rc = sqlite3_bind_text(m_Stmt, 1, filename.c_str(), filename.size(), SQLITE_STATIC);
|
||||
|
||||
if (sqlite3_step(m_Stmt) == SQLITE_ROW)
|
||||
{
|
||||
wxLogInfo("Record found, fetching..");
|
||||
|
||||
if (sqlite3_column_int(m_Stmt, 0) == 1)
|
||||
return true;
|
||||
}
|
||||
|
||||
rc = sqlite3_finalize(m_Stmt);
|
||||
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
wxMessageDialog* msgDialog = new wxMessageDialog(NULL, "Error! Cannot select sample path from table.", "Error", wxOK | wxICON_ERROR);
|
||||
msgDialog->ShowModal();
|
||||
sqlite3_free(m_ErrMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogInfo("Selected data from table successfully.");
|
||||
}
|
||||
|
||||
sqlite3_close(m_Database);
|
||||
}
|
||||
catch (const std::exception &exception)
|
||||
{
|
||||
wxLogDebug(exception.what());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Database::UpdateTrashColumn(std::string filename, int value)
|
||||
{
|
||||
try
|
||||
{
|
||||
rc = sqlite3_open("Samples.db", &m_Database);
|
||||
|
||||
std::string update = "UPDATE SAMPLES SET TRASHED = ? WHERE FILENAME = ?;";
|
||||
|
||||
rc = sqlite3_prepare_v2(m_Database, update.c_str(), update.size(), &m_Stmt, NULL);
|
||||
|
||||
rc = sqlite3_bind_int(m_Stmt, 1, value);
|
||||
rc = sqlite3_bind_text(m_Stmt, 2, filename.c_str(), filename.size(), SQLITE_STATIC);
|
||||
|
||||
if (sqlite3_step(m_Stmt) == SQLITE_ROW)
|
||||
{
|
||||
wxLogDebug("Record found, updating..");
|
||||
}
|
||||
|
||||
rc = sqlite3_finalize(m_Stmt);
|
||||
|
||||
if (rc != SQLITE_OK)
|
||||
{
|
||||
wxMessageDialog* msgDialog = new wxMessageDialog(NULL, "Error! Cannot update record.", "Error", wxOK | wxICON_ERROR);
|
||||
msgDialog->ShowModal();
|
||||
sqlite3_free(m_ErrMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogDebug("Updated record successfully.");
|
||||
}
|
||||
|
||||
sqlite3_close(m_Database);
|
||||
}
|
||||
catch (const std::exception &exception)
|
||||
{
|
||||
wxLogDebug(exception.what());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
#include <string>
|
||||
|
||||
#include <wx/infobar.h>
|
||||
#include <wx/treebase.h>
|
||||
#include <wx/treectrl.h>
|
||||
#include <wx/vector.h>
|
||||
#include <wx/variant.h>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
class Database
|
||||
{
|
||||
public:
|
||||
Database(wxInfoBar& infoBar);
|
||||
~Database();
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
sqlite3* m_Database;
|
||||
int rc;
|
||||
char* m_ErrMsg;
|
||||
sqlite3_stmt* m_Stmt;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
wxInfoBar& m_InfoBar;
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
// Insert into database
|
||||
void InsertSample(int favorite, std::string filename,
|
||||
std::string samplePack, std::string type,
|
||||
int channels, int length, int sampleRate, int bitrate,
|
||||
std::string path, int trashed);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Update database
|
||||
void UpdateFavoriteColumn(std::string filename, int value);
|
||||
void UpdateFolder(std::string folderName);
|
||||
void UpdateFavoriteFolderDatabase(std::string filename,
|
||||
std::string folderName);
|
||||
void UpdateTrashColumn(std::string filename, int value);
|
||||
void UpdateSampleType(std::string filename, std::string type);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Get from database
|
||||
std::string GetSampleType(std::string filename);
|
||||
int GetFavoriteColumnValueByFilename(std::string filename);
|
||||
std::string GetSamplePathByFilename(std::string filename);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Check database
|
||||
bool HasSample(std::string filename);
|
||||
bool IsTrashed(std::string filename);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Remove from database
|
||||
void RemoveSampleFromDatabase(std::string filename);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
wxVector<wxVector<wxVariant>>
|
||||
LoadDatabase(wxVector<wxVector<wxVariant>> &vecSet,
|
||||
wxTreeCtrl& favorite_tree, wxTreeItemId& favorite_item,
|
||||
wxTreeCtrl& trash_tree, wxTreeItemId& trash_item);
|
||||
wxVector<wxVector<wxVariant>>
|
||||
FilterDatabaseBySampleName(wxVector<wxVector<wxVariant>> &sampleVec,
|
||||
std::string sampleName);
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
#include "wx/defs.h"
|
||||
#include "wx/gdicmn.h"
|
||||
#include "wx/icon.h"
|
||||
|
||||
#include "MainFrame.hpp"
|
||||
|
||||
MainFrame::MainFrame(): wxFrame(NULL, wxID_ANY, "Sample Hive", wxDefaultPosition)
|
||||
{
|
||||
int height = 600, width = 800;
|
||||
|
||||
const std::string filepath = "config.yaml";
|
||||
Serializer serializer(filepath);
|
||||
|
||||
height = serializer.DeserializeWinSize("Height", height);
|
||||
width = serializer.DeserializeWinSize("Width", width);
|
||||
|
||||
this->SetSize(width, height);
|
||||
this->Center(wxBOTH);
|
||||
this->CenterOnScreen(wxBOTH);
|
||||
this->SetIcon(wxIcon("../assets/Icons/icon-hive_24x24.png", wxICON_DEFAULT_TYPE, -1, -1));
|
||||
|
||||
m_Browser = new Browser(this);
|
||||
}
|
||||
|
||||
MainFrame::~MainFrame(){}
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <wx/frame.h>
|
||||
|
||||
#include "Browser.hpp"
|
||||
|
||||
class MainFrame : public wxFrame
|
||||
{
|
||||
public:
|
||||
MainFrame();
|
||||
~MainFrame();
|
||||
|
||||
private:
|
||||
Browser* m_Browser;
|
||||
};
|
||||
@@ -0,0 +1,326 @@
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include <wx/log.h>
|
||||
#include <wx/stdpaths.h>
|
||||
|
||||
#include "Serialize.hpp"
|
||||
|
||||
Serializer::Serializer(const std::string& filepath)
|
||||
: m_Filepath(filepath)
|
||||
{
|
||||
std::ifstream ifstrm(m_Filepath);
|
||||
|
||||
wxFont font = wxSystemSettings::GetFont(wxSYS_SYSTEM_FONT);
|
||||
std::string system_font_face = font.GetFaceName().ToStdString();
|
||||
int system_font_size = font.GetPointSize();
|
||||
|
||||
std::string dir = wxStandardPaths::Get().GetDocumentsDir().ToStdString();
|
||||
|
||||
if (!ifstrm)
|
||||
{
|
||||
m_Emitter << YAML::Comment("Hello");
|
||||
m_Emitter << YAML::BeginDoc;
|
||||
m_Emitter << "This is the configuration file for the Sample Browser,"
|
||||
<< YAML::Newline;
|
||||
m_Emitter << "feel free to edit this file as needed";
|
||||
m_Emitter << YAML::EndDoc;
|
||||
|
||||
m_Emitter << YAML::BeginMap;
|
||||
|
||||
m_Emitter << YAML::Newline << YAML::Key << "Window";
|
||||
m_Emitter << YAML::BeginMap;
|
||||
m_Emitter << YAML::Key << "Width" << YAML::Value << 1280;
|
||||
m_Emitter << YAML::Key << "Height" << YAML::Value << 720;
|
||||
m_Emitter << YAML::EndMap << YAML::Newline;
|
||||
|
||||
m_Emitter << YAML::Newline << YAML::Key << "Media";
|
||||
m_Emitter << YAML::BeginMap;
|
||||
m_Emitter << YAML::Key << "Autoplay" << YAML::Value << false;
|
||||
m_Emitter << YAML::Key << "Loop" << YAML::Value << false;
|
||||
m_Emitter << YAML::Key << "Muted" << YAML::Value << false;
|
||||
m_Emitter << YAML::EndMap << YAML::Newline;
|
||||
|
||||
m_Emitter << YAML::Newline << YAML::Key << "Display";
|
||||
m_Emitter << YAML::BeginMap;
|
||||
m_Emitter << YAML::Key << "Font";
|
||||
m_Emitter << YAML::BeginMap;
|
||||
m_Emitter << YAML::Key << "Family" << YAML::Value << system_font_face;
|
||||
m_Emitter << YAML::Key << "Size" << YAML::Value << system_font_size;
|
||||
m_Emitter << YAML::EndMap;
|
||||
m_Emitter << YAML::EndMap << YAML::Newline;
|
||||
|
||||
m_Emitter << YAML::Newline << YAML::Key << "Import_dir";
|
||||
m_Emitter << YAML::BeginMap;
|
||||
m_Emitter << YAML::Key << "AutoImport" << YAML::Value << false;
|
||||
m_Emitter << YAML::Key << "Directory" << YAML::Value << dir;
|
||||
m_Emitter << YAML::EndMap << YAML::Newline;
|
||||
|
||||
m_Emitter << YAML::EndMap;
|
||||
|
||||
std::ofstream ofstrm(m_Filepath);
|
||||
ofstrm << m_Emitter.c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogDebug("Config file already exists! Skipping..");
|
||||
}
|
||||
}
|
||||
|
||||
Serializer::~Serializer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int Serializer::DeserializeWinSize(std::string key, int size) const
|
||||
{
|
||||
int width = 800, height = 600;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node data = YAML::LoadAllFromFile(m_Filepath)[1];
|
||||
|
||||
if (!data["Window"])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (auto win = data["Window"])
|
||||
{
|
||||
if (key == "Height")
|
||||
{
|
||||
size = height;
|
||||
size = win["Height"].as<int>();
|
||||
}
|
||||
|
||||
if (key == "Width")
|
||||
{
|
||||
size = width;
|
||||
size = win["Width"].as<int>();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(const YAML::ParserException& ex)
|
||||
{
|
||||
std::cout << ex.what() << std::endl;
|
||||
}
|
||||
|
||||
wxLogDebug("size: %d", size);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
bool Serializer::DeserializeBrowserControls(std::string key, bool control) const
|
||||
{
|
||||
bool autoplay = false; bool loop = false; bool muted = false;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadAllFromFile(m_Filepath)[1];
|
||||
|
||||
if (auto media = config["Media"])
|
||||
{
|
||||
if (key == "autoplay")
|
||||
{
|
||||
control = autoplay;
|
||||
autoplay = media["Autoplay"].as<bool>();
|
||||
}
|
||||
|
||||
if (key == "loop")
|
||||
{
|
||||
control = loop;
|
||||
loop = media["Loop"].as<bool>();
|
||||
}
|
||||
|
||||
if (key == "muted")
|
||||
{
|
||||
control = muted;
|
||||
muted = media["Muted"].as<bool>();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogDebug("Error! Cannot fetch values.");
|
||||
}
|
||||
}
|
||||
catch(const YAML::ParserException& ex)
|
||||
{
|
||||
std::cout << ex.what() << std::endl;
|
||||
}
|
||||
|
||||
wxLogDebug("Control: %d", control);
|
||||
|
||||
return control;
|
||||
}
|
||||
|
||||
void Serializer::SerializeDisplaySettings(wxFont& font)
|
||||
{
|
||||
YAML::Emitter out;
|
||||
|
||||
std::string font_face = font.GetFaceName().ToStdString();
|
||||
int font_size = font.GetPointSize();
|
||||
|
||||
try
|
||||
{
|
||||
auto docs = YAML::LoadAllFromFile(m_Filepath);
|
||||
out << YAML::Comment("Hello") << YAML::BeginDoc << docs[0] << YAML::EndDoc;
|
||||
|
||||
YAML::Node config = docs[1];
|
||||
// YAML::Node config = YAML::LoadAllFromFile(m_Filepath)[1];
|
||||
|
||||
auto display = config["Display"];
|
||||
|
||||
if (auto fontSetting = display["Font"])
|
||||
{
|
||||
wxLogDebug("Changing font settings");
|
||||
wxLogDebug("Font face: %s", font_face);
|
||||
wxLogDebug("Font size: %d", font_size);
|
||||
|
||||
fontSetting["Family"] = font_face;
|
||||
fontSetting["Size"] = font_size;
|
||||
|
||||
out << config;
|
||||
|
||||
std::ofstream ofstrm(m_Filepath);
|
||||
ofstrm << out.c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogDebug("Error! Cannot store font values.");
|
||||
}
|
||||
}
|
||||
catch(const YAML::ParserException& ex)
|
||||
{
|
||||
std::cout << ex.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
FontType Serializer::DeserializeDisplaySettings() const
|
||||
{
|
||||
wxString face;
|
||||
int size = 0 ;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadAllFromFile(m_Filepath)[1];
|
||||
|
||||
auto display = config["Display"];
|
||||
|
||||
if (auto font_setting = display["Font"])
|
||||
{
|
||||
face = font_setting["Family"].as<std::string>();
|
||||
size = font_setting["Size"].as<int>();
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogDebug("Error! Cannot fetch font values.");
|
||||
}
|
||||
}
|
||||
catch(const YAML::ParserException& ex)
|
||||
{
|
||||
std::cout << ex.what() << std::endl;
|
||||
}
|
||||
|
||||
return { face, size };
|
||||
}
|
||||
|
||||
void Serializer::SerializeAutoImportSettings(wxTextCtrl& textCtrl, wxCheckBox& checkBox)
|
||||
{
|
||||
YAML::Emitter out;
|
||||
|
||||
std::string import_dir = textCtrl.GetValue().ToStdString();
|
||||
bool auto_import = checkBox.GetValue();
|
||||
|
||||
try
|
||||
{
|
||||
auto docs = YAML::LoadAllFromFile(m_Filepath);
|
||||
out << YAML::Comment("Hello") << YAML::BeginDoc << docs[0] << YAML::EndDoc;
|
||||
|
||||
YAML::Node config = docs[1];
|
||||
// YAML::Node config = YAML::LoadAllFromFile(m_Filepath)[1];
|
||||
|
||||
if (auto importInfo = config["Import_dir"])
|
||||
{
|
||||
importInfo["AutoImport"] = auto_import;
|
||||
importInfo["Directory"] = import_dir;
|
||||
|
||||
out << config;
|
||||
|
||||
std::ofstream ofstrm(m_Filepath);
|
||||
ofstrm << out.c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogDebug("Error! Cannot store import dir values.");
|
||||
}
|
||||
}
|
||||
catch(const YAML::ParserException& ex)
|
||||
{
|
||||
std::cout << ex.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
ImportDirInfo Serializer::DeserializeAutoImportSettings() const
|
||||
{
|
||||
wxString dir;
|
||||
bool auto_import = false;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadAllFromFile(m_Filepath)[1];
|
||||
|
||||
if (auto importInfo = config["Import_dir"])
|
||||
{
|
||||
auto_import = importInfo["AutoImport"].as<bool>();
|
||||
dir = importInfo["Directory"].as<std::string>();
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogDebug("Error! Cannot fetch import dir values.");
|
||||
}
|
||||
}
|
||||
catch(const YAML::ParserException& ex)
|
||||
{
|
||||
std::cout << ex.what() << std::endl;
|
||||
}
|
||||
|
||||
return { auto_import, dir };
|
||||
}
|
||||
|
||||
void Serializer::SerializeDataViewTreeCtrlItems(wxTreeCtrl& tree, wxTreeItemId& item)
|
||||
{
|
||||
std::string path = "tree.yaml";
|
||||
|
||||
std::ifstream ifstrm(path);
|
||||
|
||||
YAML::Emitter out;
|
||||
|
||||
out << YAML::BeginMap; // Container
|
||||
out << YAML::Key << "Container" << YAML::Value << "";
|
||||
|
||||
if (tree.HasChildren(item))
|
||||
{
|
||||
out << YAML::Key << "Child";
|
||||
out << YAML::BeginMap; // Child
|
||||
|
||||
for ( size_t i = 0; i < tree.GetChildrenCount(item); i++ )
|
||||
{
|
||||
// wxTreeItemIdValue cookie;
|
||||
wxString child = tree.GetItemText(tree.GetSelection());
|
||||
out << YAML::Key << "Item" << YAML::Value << child.ToStdString();
|
||||
}
|
||||
|
||||
out << YAML::EndMap; // Child
|
||||
}
|
||||
|
||||
out << YAML::EndMap; // Container
|
||||
|
||||
std::ofstream ofstrm(path);
|
||||
ofstrm << out.c_str();
|
||||
}
|
||||
|
||||
bool Serializer::DeserializeDataViewTreeCtrlItems(YAML::Emitter &out, wxDataViewItem item) const
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
#include <string>
|
||||
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/dataview.h>
|
||||
#include <wx/font.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/treebase.h>
|
||||
#include <wx/treectrl.h>
|
||||
|
||||
#include <yaml-cpp/yaml.h>
|
||||
#include <yaml-cpp/emitter.h>
|
||||
#include <yaml-cpp/emittermanip.h>
|
||||
#include <yaml-cpp/exceptions.h>
|
||||
#include <yaml-cpp/node/node.h>
|
||||
#include <yaml-cpp/node/parse.h>
|
||||
#include <yaml-cpp/null.h>
|
||||
#include <yaml-cpp/emittermanip.h>
|
||||
|
||||
struct FontType
|
||||
{
|
||||
wxString font_face;
|
||||
int font_size;
|
||||
};
|
||||
|
||||
struct ImportDirInfo
|
||||
{
|
||||
bool auto_import;
|
||||
wxString import_dir;
|
||||
};
|
||||
|
||||
class Serializer
|
||||
{
|
||||
public:
|
||||
Serializer(const std::string& filepath);
|
||||
~Serializer();
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
const std::string& m_Filepath;
|
||||
|
||||
YAML::Emitter m_Emitter;
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
// Window size
|
||||
int DeserializeWinSize(std::string key, int size) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Browser controls
|
||||
void SerializeBrowserControls();
|
||||
bool DeserializeBrowserControls(std::string key, bool control) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Display settings
|
||||
void SerializeDisplaySettings(wxFont& font);
|
||||
FontType DeserializeDisplaySettings() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Auto import settings
|
||||
void SerializeAutoImportSettings(wxTextCtrl& textCtrl, wxCheckBox& checkBox);
|
||||
ImportDirInfo DeserializeAutoImportSettings() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Favorite samples
|
||||
void SerializeDataViewTreeCtrlItems(wxTreeCtrl& tree, wxTreeItemId& item);
|
||||
bool DeserializeDataViewTreeCtrlItems(YAML::Emitter& out, wxDataViewItem item) const;
|
||||
};
|
||||
@@ -0,0 +1,384 @@
|
||||
#include <wx/defs.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/log.h>
|
||||
#include <wx/stdpaths.h>
|
||||
#include <wx/stringimpl.h>
|
||||
|
||||
#include "ControlID_Enums.hpp"
|
||||
#include "SettingsDialog.hpp"
|
||||
#include "Serialize.hpp"
|
||||
|
||||
Settings::Settings(wxWindow* window, std::string& configFilepath, std::string& databaseFilepath)
|
||||
: wxDialog(window, wxID_ANY, "Settings", wxDefaultPosition,
|
||||
wxSize(720, 270), wxDEFAULT_DIALOG_STYLE | wxSTAY_ON_TOP),
|
||||
m_Window(window), m_ConfigFilepath(configFilepath), m_DatabaseFilepath(databaseFilepath)
|
||||
{
|
||||
m_Panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
m_MainSizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_NotebookSizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_ButtonSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
m_Notebook = new wxNotebook(m_Panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, _T("NOTEBOOK"));
|
||||
|
||||
m_DisplaySettingPanel = new wxPanel(m_Notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
m_DisplayTopSizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_DisplayFontSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
wxString fontChoices[] = {"System default"};
|
||||
// m_RowHeightText = new wxStaticText();
|
||||
m_FontTypeText = new wxStaticText(m_DisplaySettingPanel, wxID_ANY, "Font", wxDefaultPosition, wxDefaultSize, 0);
|
||||
// m_RowHeight = new wxChoice();
|
||||
m_FontType = new wxChoice(m_DisplaySettingPanel, SD_FontType, wxDefaultPosition, wxDefaultSize, 1, fontChoices, 0);
|
||||
m_FontType->SetSelection(0);
|
||||
m_FontSize = new wxSpinCtrl(m_DisplaySettingPanel, SD_FontSize, "Default", wxDefaultPosition, wxDefaultSize);
|
||||
m_FontSize->SetValue(window->GetFont().GetPointSize());
|
||||
m_FontBrowseButton = new wxButton(m_DisplaySettingPanel, SD_FontBrowseButton, "Select font", wxDefaultPosition, wxDefaultSize, 0);
|
||||
|
||||
m_CollectionSettingPanel = new wxPanel(m_Notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
m_CollectionTopSizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_CollectionImportDirSizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
wxString defaultDir = wxStandardPaths::Get().GetDocumentsDir();
|
||||
|
||||
m_AutoImportCheck = new wxCheckBox(m_CollectionSettingPanel, SD_AutoImport, "Auto import", wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_ImportDirLocation = new wxTextCtrl(m_CollectionSettingPanel, wxID_ANY, defaultDir, wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_ImportDirLocation->Disable();
|
||||
m_BrowseAutoImportDirButton = new wxButton(m_CollectionSettingPanel, SD_BrowseAutoImportDir, "Browse", wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_BrowseAutoImportDirButton->Disable();
|
||||
|
||||
m_ConfigurationSettingPanel = new wxPanel(m_Notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
m_GeneralMainSizer = new wxFlexGridSizer(2, 3, 0, 0);
|
||||
m_GeneralMainSizer->AddGrowableCol(1);
|
||||
m_GeneralMainSizer->SetFlexibleDirection(wxBOTH);
|
||||
m_GeneralMainSizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
|
||||
|
||||
m_ConfigLabel = new wxStaticText(m_ConfigurationSettingPanel, wxID_ANY, "Default configuration file location", wxDefaultPosition, wxDefaultSize);
|
||||
m_ConfigText = new wxTextCtrl(m_ConfigurationSettingPanel, wxID_ANY, configFilepath, wxDefaultPosition, wxDefaultSize);
|
||||
m_ConfigBrowse = new wxButton(m_ConfigurationSettingPanel, SD_BrowseConfigDir, "Browse", wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_DatabaseLabel = new wxStaticText(m_ConfigurationSettingPanel, wxID_ANY, "Default database location", wxDefaultPosition, wxDefaultSize);
|
||||
m_DatabaseText = new wxTextCtrl(m_ConfigurationSettingPanel, wxID_ANY, databaseFilepath, wxDefaultPosition, wxDefaultSize);
|
||||
m_DatabaseBrowse = new wxButton(m_ConfigurationSettingPanel, SD_BrowseDatabaseDir, "Browse", wxDefaultPosition, wxDefaultSize, 0);
|
||||
|
||||
m_Notebook->AddPage(m_DisplaySettingPanel, "Display");
|
||||
m_Notebook->AddPage(m_CollectionSettingPanel, "Collection");
|
||||
m_Notebook->AddPage(m_ConfigurationSettingPanel, "General");
|
||||
|
||||
m_OkButton = new wxButton(m_Panel, wxID_OK, "OK", wxDefaultPosition, wxDefaultSize);
|
||||
m_CancelButton = new wxButton(m_Panel, wxID_CANCEL, "Cancel", wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
LoadDefaultConfig();
|
||||
|
||||
// Bind events
|
||||
Bind(wxEVT_CHECKBOX, &Settings::OnCheckAutoImport, this, SD_AutoImport);
|
||||
Bind(wxEVT_SPINCTRL, &Settings::OnChangeFontSize, this, SD_FontSize);
|
||||
Bind(wxEVT_BUTTON, &Settings::OnSelectFont, this, SD_FontBrowseButton);
|
||||
Bind(wxEVT_BUTTON, &Settings::OnClickBrowseAutoImportDir, this, SD_BrowseAutoImportDir);
|
||||
Bind(wxEVT_BUTTON, &Settings::OnClickConfigBrowse, this, SD_BrowseConfigDir);
|
||||
Bind(wxEVT_BUTTON, &Settings::OnClickDatabaseBrowse, this, SD_BrowseDatabaseDir);
|
||||
|
||||
// Adding controls to sizers
|
||||
m_NotebookSizer->Add(m_Notebook, 1, wxALL | wxEXPAND, 2);
|
||||
|
||||
m_GeneralMainSizer->Add(m_ConfigLabel, 0, wxALL | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_GeneralMainSizer->Add(m_ConfigText, 1, wxALL | wxALIGN_CENTER_VERTICAL | wxEXPAND, 2);
|
||||
m_GeneralMainSizer->Add(m_ConfigBrowse, 0, wxALL | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, 2);
|
||||
|
||||
m_GeneralMainSizer->Add(m_DatabaseLabel, 0, wxALL | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_GeneralMainSizer->Add(m_DatabaseText, 1, wxALL | wxALIGN_CENTER_VERTICAL | wxEXPAND, 2);
|
||||
m_GeneralMainSizer->Add(m_DatabaseBrowse, 0, wxALL | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, 2);
|
||||
|
||||
m_DisplayFontSizer->Add(m_FontTypeText, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_DisplayFontSizer->Add(m_FontType, 1, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_DisplayFontSizer->Add(m_FontSize, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_DisplayFontSizer->Add(m_FontBrowseButton, 0, wxALL | wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT, 2);
|
||||
|
||||
m_DisplayTopSizer->Add(m_DisplayFontSizer, 1, wxALL | wxEXPAND, 2);
|
||||
|
||||
m_CollectionImportDirSizer->Add(m_AutoImportCheck, 0, wxALL, 2);
|
||||
m_CollectionImportDirSizer->Add(m_ImportDirLocation, 0, wxALL | wxEXPAND, 2);
|
||||
m_CollectionImportDirSizer->Add(m_BrowseAutoImportDirButton, 0, wxALL, 2);
|
||||
|
||||
m_CollectionTopSizer->Add(m_CollectionImportDirSizer, 1, wxALL | wxEXPAND, 2);
|
||||
|
||||
m_ButtonSizer->Add(m_OkButton, 0, wxALL | wxALIGN_BOTTOM, 2);
|
||||
m_ButtonSizer->Add(m_CancelButton, 0, wxALL | wxALIGN_BOTTOM, 2);
|
||||
|
||||
m_MainSizer->Add(m_NotebookSizer, 1, wxALL | wxEXPAND, 2);
|
||||
m_MainSizer->Add(m_ButtonSizer, 0, wxALL | wxALIGN_RIGHT, 2);
|
||||
|
||||
// Top panel layout
|
||||
m_Panel->SetSizer(m_MainSizer);
|
||||
m_MainSizer->Fit(m_Panel);
|
||||
m_MainSizer->SetSizeHints(m_Panel);
|
||||
m_MainSizer->Layout();
|
||||
|
||||
// Display panel layout
|
||||
m_DisplaySettingPanel->SetSizer(m_DisplayTopSizer);
|
||||
m_DisplayTopSizer->Fit(m_DisplaySettingPanel);
|
||||
m_DisplayTopSizer->SetSizeHints(m_DisplaySettingPanel);
|
||||
m_DisplayTopSizer->Layout();
|
||||
|
||||
// Collection panel layout
|
||||
m_CollectionSettingPanel->SetSizer(m_CollectionTopSizer);
|
||||
m_CollectionTopSizer->Fit(m_CollectionSettingPanel);
|
||||
m_CollectionTopSizer->SetSizeHints(m_CollectionSettingPanel);
|
||||
m_CollectionTopSizer->Layout();
|
||||
|
||||
// Configuration panel layout
|
||||
m_ConfigurationSettingPanel->SetSizer(m_GeneralMainSizer);
|
||||
m_GeneralMainSizer->Fit(m_ConfigurationSettingPanel);
|
||||
m_GeneralMainSizer->SetSizeHints(m_ConfigurationSettingPanel);
|
||||
m_GeneralMainSizer->Layout();
|
||||
}
|
||||
|
||||
void Settings::OnClickConfigBrowse(wxCommandEvent& event)
|
||||
{
|
||||
wxString initial_dir = wxStandardPaths::Get().GetDocumentsDir();
|
||||
|
||||
m_DirDialog = new wxDirDialog(this, "Select a directory..", initial_dir,
|
||||
wxDD_DEFAULT_STYLE |
|
||||
wxDD_DIR_MUST_EXIST |
|
||||
wxDD_NEW_DIR_BUTTON,
|
||||
wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
switch (m_DirDialog->ShowModal())
|
||||
{
|
||||
case wxID_OK:
|
||||
{
|
||||
wxString path = m_DirDialog->GetPath();
|
||||
m_ConfigText->SetValue(path + "/config.yaml");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Settings::OnClickDatabaseBrowse(wxCommandEvent& event)
|
||||
{
|
||||
wxString initial_dir = wxStandardPaths::Get().GetDocumentsDir();
|
||||
|
||||
m_DirDialog = new wxDirDialog(this, "Select a directory..", initial_dir,
|
||||
wxDD_DEFAULT_STYLE |
|
||||
wxDD_DIR_MUST_EXIST |
|
||||
wxDD_NEW_DIR_BUTTON,
|
||||
wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
switch (m_DirDialog->ShowModal())
|
||||
{
|
||||
case wxID_OK:
|
||||
{
|
||||
wxString path = m_DirDialog->GetPath();
|
||||
m_DatabaseText->SetValue(path + "/config.yaml");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Settings::OnCheckAutoImport(wxCommandEvent& event)
|
||||
{
|
||||
Serializer serializer(m_ConfigFilepath);
|
||||
|
||||
if (!m_AutoImportCheck->GetValue())
|
||||
{
|
||||
bAutoImport = false;
|
||||
m_ImportDirLocation->Disable();
|
||||
m_BrowseAutoImportDirButton->Disable();
|
||||
|
||||
serializer.SerializeAutoImportSettings(*m_ImportDirLocation, *m_AutoImportCheck);
|
||||
}
|
||||
else
|
||||
{
|
||||
bAutoImport = true;
|
||||
m_ImportDirLocation->Enable();
|
||||
m_BrowseAutoImportDirButton->Enable();
|
||||
|
||||
serializer.SerializeAutoImportSettings(*m_ImportDirLocation, *m_AutoImportCheck);
|
||||
}
|
||||
}
|
||||
|
||||
void Settings::OnClickBrowseAutoImportDir(wxCommandEvent& event)
|
||||
{
|
||||
Serializer serializer(m_ConfigFilepath);
|
||||
|
||||
wxString initial_dir = wxStandardPaths::Get().GetDocumentsDir();
|
||||
|
||||
m_DirDialog = new wxDirDialog(this, "Select a directory..", initial_dir,
|
||||
wxDD_DEFAULT_STYLE |
|
||||
wxDD_DIR_MUST_EXIST |
|
||||
wxDD_NEW_DIR_BUTTON,
|
||||
wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
switch (m_DirDialog->ShowModal())
|
||||
{
|
||||
case wxID_OK:
|
||||
{
|
||||
wxLogDebug("Import DIR OKAY..");
|
||||
wxString path = m_DirDialog->GetPath();
|
||||
m_ImportDirLocation->SetValue(path);
|
||||
|
||||
serializer.SerializeAutoImportSettings(*m_ImportDirLocation, *m_AutoImportCheck);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Settings::OnSelectFont(wxCommandEvent& event)
|
||||
{
|
||||
m_FontDialog = new wxFontDialog(this);
|
||||
|
||||
switch (m_FontDialog->ShowModal())
|
||||
{
|
||||
case wxID_OK:
|
||||
{
|
||||
wxFontData fontData = m_FontDialog->GetFontData();
|
||||
m_Font = fontData.GetChosenFont();
|
||||
|
||||
if (m_FontType->GetCount() > 1)
|
||||
{
|
||||
m_FontType->Delete(1);
|
||||
m_FontType->AppendString(m_Font.GetFaceName());
|
||||
m_FontType->SetSelection(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_FontType->AppendString(m_Font.GetFaceName());
|
||||
m_FontType->SetSelection(1);
|
||||
}
|
||||
|
||||
SetCustomFont();
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
PrintFont();
|
||||
}
|
||||
|
||||
void Settings::OnChangeFontSize(wxSpinEvent& event)
|
||||
{
|
||||
Serializer serializer(m_ConfigFilepath);
|
||||
|
||||
int font_size = m_FontSize->GetValue();
|
||||
|
||||
if ( m_FontType->GetStringSelection() == "System default" )
|
||||
m_Font = wxSystemSettings::GetFont(wxSYS_SYSTEM_FONT);
|
||||
|
||||
m_Font.SetPointSize(font_size);
|
||||
|
||||
serializer.SerializeDisplaySettings(m_Font);
|
||||
|
||||
m_Window->SetFont(m_Font);
|
||||
this->SetFont(m_Font);
|
||||
|
||||
wxLogDebug("Font size: %d", font_size);
|
||||
wxLogDebug("Font size: %d", m_Font.GetPointSize());
|
||||
}
|
||||
|
||||
void Settings::LoadDefaultConfig()
|
||||
{
|
||||
Serializer serializer(m_ConfigFilepath);
|
||||
|
||||
wxFont sys_font = wxSystemSettings::GetFont(wxSYS_SYSTEM_FONT);
|
||||
std::string system_font = sys_font.GetFaceName().ToStdString();
|
||||
int system_font_size = sys_font.GetPointSize();
|
||||
|
||||
wxString font_face = serializer.DeserializeDisplaySettings().font_face;
|
||||
int font_size = serializer.DeserializeDisplaySettings().font_size;
|
||||
|
||||
if ( system_font != font_face )
|
||||
{
|
||||
if (m_FontType->GetCount() > 1)
|
||||
{
|
||||
m_FontType->Delete(1);
|
||||
m_FontType->AppendString(font_face);
|
||||
m_FontType->SetSelection(1);
|
||||
|
||||
m_Font.SetFaceName(font_face);
|
||||
m_Font.SetPointSize(font_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_FontType->AppendString(font_face);
|
||||
m_FontType->SetSelection(1);
|
||||
|
||||
m_Font.SetFaceName(font_face);
|
||||
m_Font.SetPointSize(font_size);
|
||||
}
|
||||
}
|
||||
|
||||
m_FontSize->SetValue(font_size);
|
||||
SetCustomFont();
|
||||
|
||||
bool import_check = serializer.DeserializeAutoImportSettings().auto_import;
|
||||
wxString location = serializer.DeserializeAutoImportSettings().import_dir;
|
||||
|
||||
m_AutoImportCheck->SetValue(import_check);
|
||||
m_ImportDirLocation->SetValue(location);
|
||||
|
||||
if (import_check)
|
||||
{
|
||||
m_ImportDirLocation->Enable();
|
||||
m_BrowseAutoImportDirButton->Enable();
|
||||
}
|
||||
}
|
||||
|
||||
void Settings::PrintFont()
|
||||
{
|
||||
wxLogDebug("Font face: %s", m_Font.GetFaceName());
|
||||
wxLogDebug("Font size: %d", m_Font.GetPointSize());
|
||||
wxLogDebug("Font family: %s", m_Font.GetFamilyString());
|
||||
wxLogDebug("Font style: %s", m_Font.GetStyleString());
|
||||
wxLogDebug("Font weight: %s", m_Font.GetWeightString());
|
||||
}
|
||||
|
||||
void Settings::SetCustomFont()
|
||||
{
|
||||
Serializer serializer(m_ConfigFilepath);
|
||||
|
||||
wxFont sys_font = wxSystemSettings::GetFont(wxSYS_SYSTEM_FONT);
|
||||
std::string system_font = sys_font.GetFaceName().ToStdString();
|
||||
int system_font_size = sys_font.GetPointSize();
|
||||
|
||||
wxString font_face = serializer.DeserializeDisplaySettings().font_face;
|
||||
int font_size = serializer.DeserializeDisplaySettings().font_size;
|
||||
|
||||
if ( m_FontType->GetStringSelection() == "System default" )
|
||||
{
|
||||
wxLogDebug("Setting default font");
|
||||
|
||||
m_Window->SetFont(sys_font);
|
||||
this->SetFont(sys_font);
|
||||
|
||||
serializer.SerializeDisplaySettings(sys_font);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogDebug("Setting custom font");
|
||||
|
||||
m_Window->SetFont(m_Font);
|
||||
this->SetFont(m_Font);
|
||||
|
||||
serializer.SerializeDisplaySettings(m_Font);
|
||||
}
|
||||
}
|
||||
|
||||
wxString Settings::GetImportDirPath()
|
||||
{
|
||||
wxString dir = wxEmptyString;
|
||||
|
||||
if (m_AutoImportCheck->GetValue())
|
||||
dir = m_ImportDirLocation->GetValue();
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
Settings::~Settings(){}
|
||||
@@ -0,0 +1,121 @@
|
||||
#pragma once
|
||||
|
||||
#include <wx/button.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/choice.h>
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/dirdlg.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/fontdlg.h>
|
||||
#include <wx/notebook.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/spinctrl.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/toplevel.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
class Settings : public wxDialog
|
||||
{
|
||||
public:
|
||||
Settings(wxWindow* window, std::string& configFilepath, std::string& databaseFilepath);
|
||||
~Settings();
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
wxWindow* m_Window;
|
||||
|
||||
std::string& m_ConfigFilepath;
|
||||
std::string& m_DatabaseFilepath;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
// Top panel for wxDialog
|
||||
wxPanel* m_Panel;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Notebook page panels
|
||||
wxPanel* m_DisplaySettingPanel;
|
||||
wxPanel* m_CollectionSettingPanel;
|
||||
wxPanel* m_ConfigurationSettingPanel;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Top panel sizers
|
||||
wxBoxSizer* m_MainSizer;
|
||||
wxBoxSizer* m_NotebookSizer;
|
||||
wxBoxSizer* m_ButtonSizer;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Notebook
|
||||
wxNotebook* m_Notebook;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Display page
|
||||
wxBoxSizer* m_DisplayTopSizer;
|
||||
wxBoxSizer* m_DisplayFontSizer;
|
||||
wxStaticText* m_RowHeightText;
|
||||
wxStaticText* m_FontTypeText;
|
||||
wxChoice* m_RowHeight;
|
||||
wxChoice* m_FontType;
|
||||
wxFontDialog* m_FontDialog;
|
||||
wxButton* m_FontBrowseButton;
|
||||
wxSpinCtrl* m_FontSize;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Collection page
|
||||
wxBoxSizer* m_CollectionTopSizer;
|
||||
wxBoxSizer* m_CollectionImportDirSizer;
|
||||
wxCheckBox* m_AutoImportCheck;
|
||||
wxTextCtrl* m_ImportDirLocation;
|
||||
wxButton* m_BrowseAutoImportDirButton;
|
||||
wxDirDialog* m_DirDialog;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// General configuration page
|
||||
wxFlexGridSizer* m_GeneralMainSizer;
|
||||
wxStaticText* m_ConfigLabel;
|
||||
wxStaticText* m_DatabaseLabel;
|
||||
wxTextCtrl* m_ConfigText;
|
||||
wxTextCtrl* m_DatabaseText;
|
||||
wxButton* m_ConfigBrowse;
|
||||
wxButton* m_DatabaseBrowse;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Common buttons for wxDialog
|
||||
wxButton* m_OkButton;
|
||||
wxButton* m_CancelButton;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
wxFont m_Font;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
bool bAutoImport = false;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
void OnClickConfigBrowse(wxCommandEvent& event);
|
||||
void OnClickDatabaseBrowse(wxCommandEvent& event);
|
||||
void OnCheckAutoImport(wxCommandEvent& event);
|
||||
void OnClickBrowseAutoImportDir(wxCommandEvent& event);
|
||||
void OnChangeFontSize(wxSpinEvent& event);
|
||||
void OnSelectFont(wxCommandEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void SetCustomFont();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void LoadDefaultConfig();
|
||||
void PrintFont();
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
// Getters
|
||||
wxString GetImportDirPath();
|
||||
|
||||
inline wxFont GetFontType() { return m_Font; };
|
||||
inline bool IsAutoImport() { return bAutoImport; };
|
||||
};
|
||||
@@ -0,0 +1,294 @@
|
||||
#include <wx/defs.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/log.h>
|
||||
#include <wx/msgdlg.h>
|
||||
#include <wx/stringimpl.h>
|
||||
#include <wx/textdlg.h>
|
||||
|
||||
#include "ControlID_Enums.hpp"
|
||||
#include "Database.hpp"
|
||||
#include "TagEditorDialog.hpp"
|
||||
|
||||
TagEditor::TagEditor(wxWindow* window, std::string& filename, wxInfoBar& info_bar)
|
||||
: wxDialog(window, wxID_ANY, "Edit tags", wxDefaultPosition,
|
||||
wxSize(640, 320), wxDEFAULT_DIALOG_STYLE | wxSTAY_ON_TOP),
|
||||
m_Window(window), m_Filename(filename), m_InfoBar(info_bar), tags(filename)
|
||||
{
|
||||
m_Panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
m_MainSizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_ButtonSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_EditTagSizer = new wxFlexGridSizer(6, 2, 0, 0);
|
||||
m_EditTagSizer->AddGrowableCol(1);
|
||||
m_EditTagSizer->SetFlexibleDirection(wxBOTH);
|
||||
m_EditTagSizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
|
||||
m_SampleTypeSizer = new wxFlexGridSizer(1, 3, 0, 0);
|
||||
m_SampleTypeSizer->AddGrowableCol(1);
|
||||
m_SampleTypeSizer->SetFlexibleDirection(wxBOTH);
|
||||
m_SampleTypeSizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
|
||||
// m_StaticEditTagSizer = new wxStaticBoxSizer(wxVERTICAL, m_Panel, "Edit tags");
|
||||
// m_StaticSampleTypeSizer = new wxStaticBoxSizer(wxVERTICAL, m_Panel, "Sample type");
|
||||
|
||||
wxString choices[] = {"Kick", "Snare", "Clap", "HiHat", "Cymbal", "Cowbell", "Ride", "Tom", "Shaker", "Percussion"};
|
||||
|
||||
m_TitleCheck = new wxCheckBox(m_Panel, ET_TitleCheck, "Title", wxDefaultPosition, wxDefaultSize);
|
||||
m_ArtistCheck = new wxCheckBox(m_Panel, ET_ArtistCheck, "Artist", wxDefaultPosition, wxDefaultSize);
|
||||
m_AlbumCheck = new wxCheckBox(m_Panel, ET_AlbumCheck, "Album", wxDefaultPosition, wxDefaultSize);
|
||||
m_GenreCheck = new wxCheckBox(m_Panel, ET_GenreCheck, "Genre", wxDefaultPosition, wxDefaultSize);
|
||||
m_CommentCheck = new wxCheckBox(m_Panel, ET_CommentsCheck, "Comments", wxDefaultPosition, wxDefaultSize);
|
||||
m_SampleTypeCheck = new wxCheckBox(m_Panel, ET_TypeCheck, "Type", wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
m_TitleText = new wxTextCtrl(m_Panel, wxID_ANY, tags.GetAudioInfo().title, wxDefaultPosition, wxDefaultSize);
|
||||
m_TitleText->Disable();
|
||||
m_ArtistText = new wxTextCtrl(m_Panel, wxID_ANY, tags.GetAudioInfo().artist, wxDefaultPosition, wxDefaultSize);
|
||||
m_ArtistText->Disable();
|
||||
m_AlbumText = new wxTextCtrl(m_Panel, wxID_ANY, tags.GetAudioInfo().album, wxDefaultPosition, wxDefaultSize);
|
||||
m_AlbumText->Disable();
|
||||
m_GenreText = new wxTextCtrl(m_Panel, wxID_ANY, tags.GetAudioInfo().genre, wxDefaultPosition, wxDefaultSize);
|
||||
m_GenreText->Disable();
|
||||
m_CommentText = new wxTextCtrl(m_Panel, wxID_ANY, tags.GetAudioInfo().comment, wxDefaultPosition, wxDefaultSize);
|
||||
m_CommentText->Disable();
|
||||
m_SampleTypeChoice = new wxChoice(m_Panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 10, choices, wxCB_SORT);
|
||||
m_SampleTypeChoice->Disable();
|
||||
|
||||
m_SampleTypeButton = new wxButton(m_Panel, ET_CustomTag, "Custom", wxDefaultPosition, wxDefaultSize);
|
||||
m_SampleTypeButton->Disable();
|
||||
|
||||
m_OkButton = new wxButton(m_Panel, wxID_OK, "OK", wxDefaultPosition, wxDefaultSize);
|
||||
m_ApplyButton = new wxButton(m_Panel, wxID_APPLY, "Apply", wxDefaultPosition, wxDefaultSize);
|
||||
m_CancelButton = new wxButton(m_Panel, wxID_CANCEL, "Cancel", wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
// Binding events
|
||||
Bind(wxEVT_CHECKBOX, &TagEditor::OnCheckTitle, this, ET_TitleCheck);
|
||||
Bind(wxEVT_CHECKBOX, &TagEditor::OnCheckArtist, this, ET_ArtistCheck);
|
||||
Bind(wxEVT_CHECKBOX, &TagEditor::OnCheckAlbum, this, ET_AlbumCheck);
|
||||
Bind(wxEVT_CHECKBOX, &TagEditor::OnCheckGenre, this, ET_GenreCheck);
|
||||
Bind(wxEVT_CHECKBOX, &TagEditor::OnCheckComments, this, ET_CommentsCheck);
|
||||
Bind(wxEVT_CHECKBOX, &TagEditor::OnCheckType, this, ET_TypeCheck);
|
||||
|
||||
Bind(wxEVT_BUTTON, &TagEditor::OnClickCustomTagButton, this, ET_CustomTag);
|
||||
|
||||
Bind(wxEVT_BUTTON, &TagEditor::OnClickApply, this, wxID_APPLY);
|
||||
|
||||
m_EditTagSizer->Add(m_TitleCheck, 0, wxALL | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_EditTagSizer->Add(m_TitleText, 1, wxALL | wxALIGN_CENTER_VERTICAL | wxEXPAND, 2);
|
||||
|
||||
m_EditTagSizer->Add(m_ArtistCheck, 0, wxALL | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_EditTagSizer->Add(m_ArtistText, 1, wxALL | wxALIGN_CENTER_VERTICAL | wxEXPAND, 2);
|
||||
|
||||
m_EditTagSizer->Add(m_AlbumCheck, 0, wxALL | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_EditTagSizer->Add(m_AlbumText, 1, wxALL | wxALIGN_CENTER_VERTICAL | wxEXPAND, 2);
|
||||
|
||||
m_EditTagSizer->Add(m_GenreCheck, 0, wxALL | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_EditTagSizer->Add(m_GenreText, 1, wxALL | wxALIGN_CENTER_VERTICAL | wxEXPAND, 2);
|
||||
|
||||
m_EditTagSizer->Add(m_CommentCheck, 0, wxALL | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_EditTagSizer->Add(m_CommentText, 1, wxALL | wxALIGN_CENTER_VERTICAL | wxEXPAND, 2);
|
||||
|
||||
m_SampleTypeSizer->Add(m_SampleTypeCheck, 0, wxALL | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_SampleTypeSizer->Add(m_SampleTypeChoice, 1, wxALL | wxALIGN_CENTER_VERTICAL | wxEXPAND, 2);
|
||||
m_SampleTypeSizer->Add(m_SampleTypeButton, 0, wxALL | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, 2);
|
||||
|
||||
// m_StaticEditTagSizer->Add(m_EditTagSizer, 1, wxALL | wxEXPAND, 2);
|
||||
// m_StaticSampleTypeSizer->Add(m_SampleTypeSizer, 1, wxALL | wxEXPAND, 2);
|
||||
|
||||
m_ButtonSizer->Add(m_OkButton, 0, wxALL | wxALIGN_BOTTOM, 2);
|
||||
m_ButtonSizer->Add(m_ApplyButton, 0, wxALL | wxALIGN_BOTTOM, 2);
|
||||
m_ButtonSizer->Add(m_CancelButton, 0, wxALL | wxALIGN_BOTTOM, 2);
|
||||
|
||||
m_MainSizer->Add(m_EditTagSizer, 1, wxALL | wxEXPAND, 2);
|
||||
m_MainSizer->Add(m_SampleTypeSizer, 1, wxALL | wxEXPAND, 2);
|
||||
m_MainSizer->Add(m_ButtonSizer, 0, wxALL | wxALIGN_RIGHT, 2);
|
||||
|
||||
// Top panel layout
|
||||
m_Panel->SetSizer(m_MainSizer);
|
||||
m_MainSizer->Fit(m_Panel);
|
||||
m_MainSizer->SetSizeHints(m_Panel);
|
||||
m_MainSizer->Layout();
|
||||
}
|
||||
|
||||
void TagEditor::OnCheckTitle(wxCommandEvent &event)
|
||||
{
|
||||
if (m_TitleCheck->GetValue())
|
||||
{
|
||||
m_TitleText->Enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_TitleText->Disable();
|
||||
}
|
||||
}
|
||||
|
||||
void TagEditor::OnCheckArtist(wxCommandEvent &event)
|
||||
{
|
||||
if (m_ArtistCheck->GetValue())
|
||||
{
|
||||
m_ArtistText->Enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ArtistText->Disable();
|
||||
}
|
||||
}
|
||||
|
||||
void TagEditor::OnCheckAlbum(wxCommandEvent &event)
|
||||
{
|
||||
if (m_AlbumCheck->GetValue())
|
||||
{
|
||||
m_AlbumText->Enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_AlbumText->Disable();
|
||||
}
|
||||
}
|
||||
|
||||
void TagEditor::OnCheckGenre(wxCommandEvent &event)
|
||||
{
|
||||
if (m_GenreCheck->GetValue())
|
||||
{
|
||||
m_GenreText->Enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_GenreText->Disable();
|
||||
}
|
||||
}
|
||||
|
||||
void TagEditor::OnCheckComments(wxCommandEvent &event)
|
||||
{
|
||||
if (m_CommentCheck->GetValue())
|
||||
{
|
||||
m_CommentText->Enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CommentText->Disable();
|
||||
}
|
||||
}
|
||||
|
||||
void TagEditor::OnCheckType(wxCommandEvent &event)
|
||||
{
|
||||
if (m_SampleTypeCheck->GetValue())
|
||||
{
|
||||
m_SampleTypeChoice->Enable();
|
||||
m_SampleTypeButton->Enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_SampleTypeChoice->Disable();
|
||||
m_SampleTypeButton->Disable();
|
||||
}
|
||||
}
|
||||
|
||||
void TagEditor::OnClickCustomTagButton(wxCommandEvent& event)
|
||||
{
|
||||
wxTextEntryDialog* customTag;
|
||||
customTag = new wxTextEntryDialog(this, "Enter a custom tag",
|
||||
"Add custom tag", wxEmptyString,
|
||||
wxTextEntryDialogStyle, wxDefaultPosition);
|
||||
|
||||
switch (customTag->ShowModal())
|
||||
{
|
||||
case wxID_OK:
|
||||
{
|
||||
wxString tag = customTag->GetValue();
|
||||
m_SampleTypeChoice->AppendString(tag);
|
||||
m_SampleTypeChoice->SetStringSelection(tag);
|
||||
break;
|
||||
}
|
||||
case wxID_CANCEL:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void TagEditor::OnClickApply(wxCommandEvent& event)
|
||||
{
|
||||
Database db(m_InfoBar);
|
||||
|
||||
wxString title = m_TitleText->GetValue();
|
||||
wxString artist = m_ArtistText->GetValue();
|
||||
wxString album = m_AlbumText->GetValue();
|
||||
wxString genre = m_GenreText->GetValue();
|
||||
wxString comment = m_CommentText->GetValue();
|
||||
wxString type = m_SampleTypeChoice->GetStringSelection();
|
||||
wxString filename = wxString(m_Filename).AfterLast('/').BeforeLast('.');
|
||||
|
||||
std::string sampleType = db.GetSampleType(filename.ToStdString());
|
||||
|
||||
wxString warning_msg = "Are you sure you want save these changes?";
|
||||
wxMessageDialog* msgDialog = new wxMessageDialog(this, warning_msg,
|
||||
"Edit tags", wxCENTRE |
|
||||
wxYES_NO | wxNO_DEFAULT |
|
||||
wxICON_QUESTION |
|
||||
wxSTAY_ON_TOP,
|
||||
wxDefaultPosition);
|
||||
|
||||
wxString info_msg;
|
||||
|
||||
switch (msgDialog->ShowModal())
|
||||
{
|
||||
case wxID_YES:
|
||||
if (m_TitleCheck->GetValue() && m_TitleText->GetValue() != tags.GetAudioInfo().title)
|
||||
{
|
||||
wxLogDebug("Changing title tag..");
|
||||
tags.SetTitle(title.ToStdString());
|
||||
|
||||
info_msg = wxString::Format("Successfully changed title tag to %s", title);
|
||||
}
|
||||
|
||||
if (m_ArtistCheck->GetValue() && m_ArtistText->GetValue() != tags.GetAudioInfo().artist)
|
||||
{
|
||||
wxLogDebug("Changing artist tag..");
|
||||
tags.SetArtist(artist.ToStdString());
|
||||
|
||||
info_msg = wxString::Format("Successfully changed artist tag to %s", artist);
|
||||
}
|
||||
|
||||
if (m_AlbumCheck->GetValue() && m_AlbumText->GetValue() != tags.GetAudioInfo().album)
|
||||
{
|
||||
wxLogDebug("Changing album tag..");
|
||||
tags.SetAlbum(album.ToStdString());
|
||||
|
||||
info_msg = wxString::Format("Successfully changed album tag to %s", album);
|
||||
}
|
||||
|
||||
if (m_GenreCheck->GetValue() && m_GenreText->GetValue() != tags.GetAudioInfo().genre)
|
||||
{
|
||||
wxLogDebug("Changing genre tag..");
|
||||
tags.SetGenre(genre.ToStdString());
|
||||
|
||||
info_msg = wxString::Format("Successfully changed genre tag to %s", genre);
|
||||
}
|
||||
|
||||
if (m_CommentCheck->GetValue() && m_CommentText->GetValue() != tags.GetAudioInfo().comment)
|
||||
{
|
||||
wxLogDebug("Changing comment tag..");
|
||||
tags.SetComment(comment.ToStdString());
|
||||
|
||||
info_msg = wxString::Format("Successfully changed comment tag to %s", comment);
|
||||
}
|
||||
|
||||
if (m_SampleTypeCheck->GetValue() && m_SampleTypeChoice->GetStringSelection() != sampleType)
|
||||
{
|
||||
wxLogDebug("Changing type tag..");
|
||||
db.UpdateSampleType(filename.ToStdString(), type.ToStdString());
|
||||
|
||||
info_msg = wxString::Format("Successfully changed type tag to %s", type);
|
||||
}
|
||||
break;
|
||||
case wxID_NO:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
m_InfoBar.ShowMessage(info_msg, wxICON_INFORMATION);
|
||||
}
|
||||
|
||||
TagEditor::~TagEditor()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <wx/button.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/choice.h>
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/infobar.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/toplevel.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
#include "Tags.hpp"
|
||||
|
||||
class TagEditor : public wxDialog
|
||||
{
|
||||
public:
|
||||
TagEditor(wxWindow* window, std::string& filename, wxInfoBar& info_bar);
|
||||
~TagEditor();
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
wxWindow* m_Window;
|
||||
std::string& m_Filename;
|
||||
|
||||
wxInfoBar& m_InfoBar;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
// Top panel for wxDialog
|
||||
wxPanel* m_Panel;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Top panel sizers
|
||||
wxBoxSizer* m_MainSizer;
|
||||
wxFlexGridSizer* m_EditTagSizer;
|
||||
wxFlexGridSizer* m_SampleTypeSizer;
|
||||
wxBoxSizer* m_ButtonSizer;
|
||||
// wxStaticBoxSizer* m_StaticEditTagSizer;
|
||||
// wxStaticBoxSizer* m_StaticSampleTypeSizer;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Dialog controls
|
||||
wxCheckBox* m_TitleCheck;
|
||||
wxCheckBox* m_ArtistCheck;
|
||||
wxCheckBox* m_AlbumCheck;
|
||||
wxCheckBox* m_GenreCheck;
|
||||
wxCheckBox* m_CommentCheck;
|
||||
wxCheckBox* m_SampleTypeCheck;
|
||||
wxTextCtrl* m_TitleText;
|
||||
wxTextCtrl* m_ArtistText;
|
||||
wxTextCtrl* m_AlbumText;
|
||||
wxTextCtrl* m_GenreText;
|
||||
wxTextCtrl* m_CommentText;
|
||||
wxChoice* m_SampleTypeChoice;
|
||||
wxButton* m_SampleTypeButton;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Common buttons for wxDialog
|
||||
wxButton* m_OkButton;
|
||||
wxButton* m_ApplyButton;
|
||||
wxButton* m_CancelButton;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
Tags tags;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
// Toggle enable/disable items
|
||||
void OnCheckTitle(wxCommandEvent& event);
|
||||
void OnCheckArtist(wxCommandEvent& event);
|
||||
void OnCheckAlbum(wxCommandEvent& event);
|
||||
void OnCheckGenre(wxCommandEvent& event);
|
||||
void OnCheckComments(wxCommandEvent& event);
|
||||
void OnCheckType(wxCommandEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void OnClickCustomTagButton(wxCommandEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void OnClickApply(wxCommandEvent& event);
|
||||
};
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
#include <taglib/taglib.h>
|
||||
#include <taglib/fileref.h>
|
||||
#include <taglib/tstring.h>
|
||||
|
||||
#include "Tags.hpp"
|
||||
|
||||
Tags::Tags(const std::string& filename)
|
||||
: m_Filepath(filename)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Tags::~Tags()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AudioInfo Tags::GetAudioInfo()
|
||||
{
|
||||
wxString artist, album, genre, title, comment;
|
||||
int channels = 0, length = 0, sample_rate = 0, bitrate = 0;
|
||||
|
||||
TagLib::FileRef f (static_cast<const char*>(m_Filepath.c_str()), true, TagLib::AudioProperties::ReadStyle::Average);
|
||||
|
||||
if (!f.isNull() && f.tag() && f.audioProperties())
|
||||
{
|
||||
TagLib::Tag* tag = f.tag();
|
||||
TagLib::AudioProperties* properties = f.audioProperties();
|
||||
|
||||
TagLib::String Title = tag->title();
|
||||
TagLib::String Artist = tag->artist();
|
||||
TagLib::String Album = tag->album();
|
||||
TagLib::String Genre = tag->genre();
|
||||
TagLib::String Comment = tag->comment();
|
||||
|
||||
int seconds = properties->length() % 60;
|
||||
int minutes = (properties->length() - seconds) / 60;
|
||||
|
||||
bitrate = properties->bitrate();
|
||||
channels = properties->channels();
|
||||
length = properties->lengthInMilliseconds();
|
||||
int length_sec = properties->lengthInSeconds();
|
||||
sample_rate = properties->sampleRate();
|
||||
|
||||
title = wxString::FromUTF8(Title.toCString(true));
|
||||
artist = wxString::FromUTF8(Artist.toCString(true));
|
||||
album = wxString::FromUTF8(Album.toCString(true));
|
||||
genre = wxString::FromUTF8(Genre.toCString(true));
|
||||
comment = wxString::FromUTF8(Comment.toCString(true));
|
||||
|
||||
bValid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
bValid = false;
|
||||
}
|
||||
|
||||
return { title, artist, album, genre, comment, channels, length, sample_rate, bitrate };
|
||||
}
|
||||
|
||||
void Tags::SetTitle(std::string title)
|
||||
{
|
||||
TagLib::FileRef f (static_cast<const char*>(m_Filepath.c_str()), true, TagLib::AudioProperties::ReadStyle::Average);
|
||||
|
||||
if (!f.isNull() && f.tag() && f.audioProperties())
|
||||
{
|
||||
TagLib::Tag* tag = f.tag();
|
||||
|
||||
tag->setTitle(title);
|
||||
f.save();
|
||||
}
|
||||
}
|
||||
|
||||
void Tags::SetArtist(std::string artist)
|
||||
{
|
||||
TagLib::FileRef f (static_cast<const char*>(m_Filepath.c_str()), true, TagLib::AudioProperties::ReadStyle::Average);
|
||||
|
||||
if (!f.isNull() && f.tag() && f.audioProperties())
|
||||
{
|
||||
TagLib::Tag* tag = f.tag();
|
||||
|
||||
tag->setArtist(artist);
|
||||
f.save();
|
||||
}
|
||||
}
|
||||
|
||||
void Tags::SetAlbum(std::string album)
|
||||
{
|
||||
TagLib::FileRef f (static_cast<const char*>(m_Filepath.c_str()), true, TagLib::AudioProperties::ReadStyle::Average);
|
||||
|
||||
if (!f.isNull() && f.tag() && f.audioProperties())
|
||||
{
|
||||
TagLib::Tag* tag = f.tag();
|
||||
|
||||
tag->setAlbum(album);
|
||||
f.save();
|
||||
}
|
||||
}
|
||||
|
||||
void Tags::SetGenre(std::string genre)
|
||||
{
|
||||
TagLib::FileRef f (static_cast<const char*>(m_Filepath.c_str()), true, TagLib::AudioProperties::ReadStyle::Average);
|
||||
|
||||
if (!f.isNull() && f.tag() && f.audioProperties())
|
||||
{
|
||||
TagLib::Tag* tag = f.tag();
|
||||
|
||||
tag->setGenre(genre);
|
||||
f.save();
|
||||
}
|
||||
}
|
||||
|
||||
void Tags::SetComment(std::string comment)
|
||||
{
|
||||
TagLib::FileRef f (static_cast<const char*>(m_Filepath.c_str()), true, TagLib::AudioProperties::ReadStyle::Average);
|
||||
|
||||
if (!f.isNull() && f.tag() && f.audioProperties())
|
||||
{
|
||||
TagLib::Tag* tag = f.tag();
|
||||
|
||||
tag->setComment(comment);
|
||||
f.save();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <wx/string.h>
|
||||
|
||||
struct AudioInfo
|
||||
{
|
||||
wxString title;
|
||||
wxString artist;
|
||||
wxString album;
|
||||
wxString genre;
|
||||
wxString comment;
|
||||
|
||||
int channels;
|
||||
int length;
|
||||
int sample_rate;
|
||||
int bitrate;
|
||||
};
|
||||
|
||||
class Tags
|
||||
{
|
||||
public:
|
||||
Tags(const std::string& filepath);
|
||||
~Tags();
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
const std::string& m_Filepath;
|
||||
|
||||
bool bValid = false;
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
AudioInfo GetAudioInfo();
|
||||
void SetTitle(std::string artist);
|
||||
void SetArtist(std::string artist);
|
||||
void SetAlbum(std::string album);
|
||||
void SetGenre(std::string genre);
|
||||
void SetComment(std::string comment);
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
inline bool IsFileValid() { return bValid; }
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
#include "TreeItemDialog.hpp"
|
||||
|
||||
TreeItemDialog::TreeItemDialog(wxWindow* window):
|
||||
wxDialog(window, wxID_ANY, "Add root", wxDefaultPosition, wxDefaultSize,
|
||||
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxSTAY_ON_TOP)
|
||||
{
|
||||
mainSizer = new wxBoxSizer(wxVERTICAL);
|
||||
titleSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
buttonSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
mainPanel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
addRootLabel = new wxStaticText(mainPanel, wxID_ANY, "Title", wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
addRootText = new wxTextCtrl(mainPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
addRootButton = new wxButton(mainPanel, wxID_OK, "Ok", wxDefaultPosition, wxDefaultSize, 0);
|
||||
cancelButton = new wxButton(mainPanel, wxID_CANCEL, "Cancel", wxDefaultPosition, wxDefaultSize, 0);
|
||||
|
||||
titleSizer->Add(addRootLabel, 0, wxALL, 2);
|
||||
titleSizer->Add(addRootText, 1, wxALL, 2);
|
||||
|
||||
buttonSizer->Add(addRootButton, 0, wxALL | wxALIGN_BOTTOM, 2);
|
||||
buttonSizer->Add(cancelButton, 0, wxALL | wxALIGN_BOTTOM, 2);
|
||||
|
||||
mainSizer->Add(titleSizer, 0, wxALL | wxEXPAND, 2);
|
||||
mainSizer->Add(buttonSizer, 1, wxALL | wxALIGN_RIGHT, 2);
|
||||
|
||||
mainPanel->SetSizer(mainSizer);
|
||||
mainSizer->Fit(mainPanel);
|
||||
mainSizer->SetSizeHints(mainPanel);
|
||||
mainSizer->Layout();
|
||||
}
|
||||
|
||||
TreeItemDialog::~TreeItemDialog()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <wx/button.h>
|
||||
#include <wx/defs.h>
|
||||
#include <wx/dialog.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/stringimpl.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
class TreeItemDialog : public wxDialog
|
||||
{
|
||||
public:
|
||||
TreeItemDialog(wxWindow* window);
|
||||
~TreeItemDialog();
|
||||
|
||||
public:
|
||||
wxPanel* mainPanel;
|
||||
|
||||
wxBoxSizer* mainSizer;
|
||||
wxBoxSizer* titleSizer;
|
||||
wxBoxSizer* buttonSizer;
|
||||
|
||||
wxStaticText* addRootLabel;
|
||||
|
||||
wxTextCtrl* addRootText;
|
||||
|
||||
wxButton* addRootButton;
|
||||
wxButton* cancelButton;
|
||||
};
|
||||
Reference in New Issue
Block a user