Compare commits
73 Commits
v0.8.4-alp
...
testing
| Author | SHA1 | Date |
|---|---|---|
|
|
97963fd52c | |
|
|
3f2bb4551c | |
|
|
fd2789d401 | |
|
|
023d4bca27 | |
|
|
0f1700fcdc | |
|
|
eb603be129 | |
|
|
01dad0c725 | |
|
|
7f13c45c40 | |
|
|
66ce190098 | |
|
|
c2256d8d2e | |
|
|
9a3ac45800 | |
|
|
491852a756 | |
|
|
6d0f66d144 | |
|
|
293c12a7e0 | |
|
|
22f45fbd66 | |
|
|
165e11ce6f | |
|
|
023874a9be | |
|
|
3db1e5858e | |
|
|
b367a9d895 | |
|
|
db7a476a1d | |
|
|
1ccb616b93 | |
|
|
dde610a78f | |
|
|
c9d3ab8295 | |
|
|
a14705f31f | |
|
|
490012b5eb | |
|
|
010a798fe5 | |
|
|
016fd28d34 | |
|
|
9e0be8f55a | |
|
|
1e6a0e635b | |
|
|
7dd7f2b3c1 | |
|
|
ccda509068 | |
|
|
1210b5e6ce | |
|
|
e1d89d0b24 | |
|
|
c9b79a6935 | |
|
|
f40f514912 | |
|
|
77fb65377b | |
|
|
8bfb8c718a | |
|
|
202cb1e7d8 | |
|
|
c52d7708d8 | |
|
|
5714beab03 | |
|
|
fbf26100e5 | |
|
|
0ecf694997 | |
|
|
4630695589 | |
|
|
c7005dd559 | |
|
|
3558cac62d | |
|
|
7eccf406dc | |
|
|
e00d753302 | |
|
|
63173df9ad | |
|
|
f808a8281f | |
|
|
fe463fe199 | |
|
|
1a92c58954 | |
|
|
2e656b057e | |
|
|
101dfa2474 | |
|
|
3fcea8af12 | |
|
|
601ff10690 | |
|
|
dd5b5196ee | |
|
|
79cb16324a | |
|
|
56d6d86f66 | |
|
|
28cff9a8fe | |
|
|
86a5c218ac | |
|
|
0eaf78923c | |
|
|
f061fe8a8c | |
|
|
627cb76950 | |
|
|
cf9c3f5551 | |
|
|
af929cecc2 | |
|
|
8aac911f07 | |
|
|
efc67f483c | |
|
|
fd9ec9131a | |
|
|
3e8a6fccaa | |
|
|
030c6be7c3 | |
|
|
85f534aa6e | |
|
|
d46bfdf229 | |
|
|
c49aca13a4 |
|
|
@ -1,11 +1,35 @@
|
|||
;;; Directory Local Variables
|
||||
;;; For more information see (info "(emacs) Directory Variables")
|
||||
|
||||
;; (concat (cdr (project-current))
|
||||
|
||||
((nil . ((cmake-ide-project-dir . "~/repos/sample-hive")
|
||||
|
||||
(cmake-ide-build-dir . "~/repos/sample-hive/build")
|
||||
|
||||
(cmake-ide-cmake-opts . "-DCMAKE_BUILD_TYPE=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DPORTABLE=1 -DCMAKE_CXX_COMPILER='/usr/bin/g++'")
|
||||
|
||||
;; (projectile-project-root . "~/repos/sample-hive")
|
||||
(projectile-project-name . "SampleHive")
|
||||
|
||||
(projectile-project-run-cmd . "~/repos/sample-hive/build/SampleHive")
|
||||
;; (projectile-project-run-cmd . "/tmp/SampleHive/bin/SampleHive")
|
||||
(compile-command . "ninja -C ~/repos/sample-hive/build")
|
||||
(fill-column . 110)
|
||||
;; Setup dap debugging template for the project
|
||||
(setq dap-debug-template-configurations
|
||||
'(("SampleHive::Core::Debug"
|
||||
:type "gdb"
|
||||
:request "launch"
|
||||
:name "SampleHive::Core::Debug"
|
||||
:target "${workspaceFolder}/build/SampleHive"
|
||||
;; :target "/tmp/SampleHive/bin/SampleHive"
|
||||
:cwd "${workspaceFolder}"
|
||||
:symbolLoadInfo "loadAll"
|
||||
:additionalSOLibSearchPath "/tmp/SampleHive/bin/"))))))
|
||||
|
||||
(projectile-project-test-cmd . "./test.sh"))))
|
||||
;; ((c++-mode . ((dap-debug-template-configurations . '(("SampleHive::Core::Debug"
|
||||
;; :type "gdb"
|
||||
;; :request "launch"
|
||||
;; :name "SampleHive::Core::Debug"
|
||||
;; :target "${workspaceFolder}/build/SampleHive"
|
||||
;; ;; :target "/tmp/SampleHive/bin/SampleHive"
|
||||
;; :cwd "${workspaceFolder}"
|
||||
;; :symbolLoadInfo "loadAll"
|
||||
;; :additionalSOLibSearchPath "/tmp/SampleHive/bin/"))))))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
## Quick Information
|
||||
<!-- This is to help replicate the issue as closely as possible !-->
|
||||
- **Operating System**
|
||||
- **Application version**
|
||||
|
||||
## What Happened?
|
||||
<!-- A brief description of what happened when you tried to perform an action !-->
|
||||
|
||||
## Expected result
|
||||
<!-- What should have happened when you performed the actions !-->
|
||||
|
||||
## Steps to reproduce
|
||||
<!-- List the steps required to produce the error. These should be as few as possible !-->
|
||||
|
||||
## Screenshots
|
||||
<!-- Any relevant screenshots which show the issue !-->
|
||||
|
||||
## Priority/Severity
|
||||
<!-- Delete as appropriate. The priority and severity assigned may be different to this !-->
|
||||
- [ ] High (anything that impacts the normal user flow or blocks app usage)
|
||||
- [ ] Medium (anything that negatively affects the user experience)
|
||||
- [ ] Low (anything else e.g., typos, missing icons, layout issues, etc.)
|
||||
|
||||
/label ~Bug
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
## Problem Statement
|
||||
<!-- What is the issue being faced and needs addressing? !-->
|
||||
|
||||
## Who will benefit?
|
||||
<!-- Will this fix a problem that only one user has, or will it benefit a lot of people !-->
|
||||
|
||||
## Benefits and risks
|
||||
<!--
|
||||
What benefits does this bring?
|
||||
|
||||
What risks might this introduce?
|
||||
!-->
|
||||
|
||||
## Proposed solution
|
||||
<!-- How would you like to see this issue resolved? !-->
|
||||
|
||||
## Examples
|
||||
<!-- Are there any examples of this which exist in other similar software? !-->
|
||||
|
||||
## Priority/Severity
|
||||
<!-- Delete as appropriate. The priority and severity assigned may be different to this !-->
|
||||
- [ ] High (This will bring a huge increase in performance/productivity/usability)
|
||||
- [ ] Medium (This will bring a good increase in performance/productivity/usability)
|
||||
- [ ] Low (anything else e.g., trivial, minor improvements)
|
||||
|
||||
/label ~"Feature request"
|
||||
|
|
@ -0,0 +1,229 @@
|
|||
#+TITLE: Contributing to SampleHive
|
||||
#+AUTHOR: Apoorv Singh
|
||||
#+DESCRIPTION: A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
|
||||
* Table Of Contents :toc:
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: table-of-contents
|
||||
:END:
|
||||
- [[#contributing-to-samplehive][Contributing to SampleHive]]
|
||||
- [[#what-should-i-know-before-i-get-started][What should I know before I get started?]]
|
||||
- [[#how-can-i-contribute][How Can I Contribute?]]
|
||||
- [[#styleguides][Styleguides]]
|
||||
- [[#additional-notes][Additional Notes]]
|
||||
|
||||
* Contributing to SampleHive
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: contributing-to-samplehive
|
||||
:END:
|
||||
First off, thanks for taking the time to contribute!
|
||||
|
||||
The following is a set of guidelines for contributing to [[https://gitlab.com/samplehive/sample-hive][SampleHive]], which is hosted on [[https://about.gitlab.com/][GitLab]]. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request.
|
||||
|
||||
** What should I know before I get started?
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: what-should-i-know-before-i-get-started
|
||||
:END:
|
||||
** How Can I Contribute?
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: how-can-i-contribute
|
||||
:END:
|
||||
*** Reporting Bugs
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: reporting-bugs
|
||||
:END:
|
||||
This section guides you through submitting a bug report for [[https://gitlab.com/samplehive/sample-hive][SampleHive]]. Following these guidelines helps me and the community understand your report, reproduce the behavior, and find related reports.
|
||||
|
||||
Before creating bug reports, please check [[#before-submitting-a-bug-report][this list]] as you might find out that you don't need to create one. When you are creating a bug report, please [[#how-do-i-submit-a-good-bug-report][include as many details as possible]]. Fill out [[https://gitlab.com/samplehive/sample-hive/-/blob/testing/.gitlab/issue_templates/Bug.md][the required template]], the information it asks for helps us resolve issues faster.
|
||||
|
||||
#+begin_quote
|
||||
*Note:* If you find a *Closed* issue that seems like it is the same thing that you're experiencing, do not open a new issue, instead re-open the the old one, and add a comment there, stating any additional details you want to add.
|
||||
#+end_quote
|
||||
|
||||
**** Before Submitting A Bug Report
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: before-submitting-a-bug-report
|
||||
:END:
|
||||
- *Perform a cursory search* to see if the bug has already been reported. If it has, add a comment to the existing issue instead of opening a new one.
|
||||
|
||||
**** How Do I Submit A (Good) Bug Report?
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: how-do-i-submit-a-good-bug-report
|
||||
:END:
|
||||
Explain the problem and include additional details to help me reproduce the problem:
|
||||
- *Use a clear and descriptive title* for the issue to identify the problem.
|
||||
- *Describe the exact steps which reproduce the problem* in as many details as possible.
|
||||
- *Describe the behavior you observed after following the steps* and point out what exactly is the problem with that behavior.
|
||||
- *Explain which behavior you expected to see instead and why.*
|
||||
- *Include screenshots and animated GIFs* which show you following the described steps and clearly demonstrate the problem. *You can record the GIF using* [[https://github.com/phw/peek][Peek]]
|
||||
- *If you're reporting that SampleHive crashed*, include a crash report with a stack trace from the operating system.
|
||||
|
||||
Include details about your configuration and environment:
|
||||
- *Which version of SampleHive are you using?* You can get the exact version by opening up the about dialog inside the application or you can run =SampleHive --version= in your terminal.
|
||||
- *What's the name and version of the Operating System you're using*?
|
||||
|
||||
*** Suggesting Enhancements
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: suggesting-enhancements
|
||||
:END:
|
||||
This section guides you through submitting an enhancement suggestion for SampleHive, including completely new features and minor improvements to existing functionality. Following these guidelines helps me and the community understand your suggestion and find related suggestions.
|
||||
|
||||
Before creating enhancement suggestions, please check [[#before-submitting-an-enhancement-suggestion][this list]] as you might find out that you don't need to create one. When you are creating an enhancement suggestion, please [[#how-do-i-submit-a-good-enhancement-suggestion][include as many details as possible]]. Fill out [[https://gitlab.com/samplehive/sample-hive/-/blob/testing/.gitlab/issue_templates/FeatureRequest.md][the required template]], including the steps that you imagine you would take if the feature you're requesting existed.
|
||||
|
||||
**** Before Submitting An Enhancement Suggestion
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: before-submitting-an-enhancement-suggestion
|
||||
:END:
|
||||
- *Perform a cursory search* to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one.
|
||||
|
||||
**** How Do I Submit A (Good) Enhancement Suggestion?
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: how-do-i-submit-a-good-enhancement-suggestion
|
||||
:END:
|
||||
Enhancement suggestions are tracked as [[https://docs.gitlab.com/ee/user/project/issues/][GitLab issues]]. Create an issue and provide the following information:
|
||||
|
||||
- *Use a clear and descriptive title* for the issue to identify the suggestion.
|
||||
- *Provide a step-by-step description of the suggested enhancement* in as many details as possible.
|
||||
- *Provide specific examples to demonstrate the steps*. Include copy/pasteable snippets which you use in those examples, as [[https://about.gitlab.com/handbook/markdown-guide/][Markdown code blocks]].
|
||||
- *Describe the current behavior* and *explain which behavior you expected to see instead* and why.
|
||||
- *Include screenshots and animated GIFs* which help you demonstrate the steps or point out the part of SampleHive which the suggestion is related to. You can use [[https://github.com/phw/peek][Peek]] to record GIFs.
|
||||
- *Explain why this enhancement would be useful* to most SampleHive users.
|
||||
- *List some other sample manager/browsers or similar applications where this enhancement exists.*
|
||||
- *Specify which version of SampleHive you're using.* You can get the exact version by opening up the about dialog inside the application or you can run =SampleHive --version= in your terminal.
|
||||
- *Specify the name and version of the Operating System you're using.*
|
||||
|
||||
*** Pull Requests
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: pull-requests
|
||||
:END:
|
||||
Please follow these steps to have your contribution considered by the maintainers:
|
||||
|
||||
1. Follow the [[#styleguides][styleguides]]
|
||||
|
||||
** Styleguides
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: styleguides
|
||||
:END:
|
||||
*** Git Commit Messages
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: git-commit-messages
|
||||
:END:
|
||||
- Use the present tense ("Add feature" not "Added feature")
|
||||
|
||||
*** C++ Styleguide
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: c-styleguide
|
||||
:END:
|
||||
- Formatting the body, spacing and where to put the reference or pointer symbol
|
||||
|
||||
#+begin_src c++
|
||||
// Use this
|
||||
int Function(int* param, std::string& anotherParam)
|
||||
{
|
||||
// 4 spaces
|
||||
}
|
||||
|
||||
// Instead of
|
||||
int function ( int *param, std::string &another_param ) {
|
||||
// Tabs
|
||||
}
|
||||
#+end_src
|
||||
|
||||
- Using =if= =else= =for= =while= or any of the similar statements
|
||||
|
||||
- You can leave the ={}= if there is only a single line of code after
|
||||
the statements
|
||||
|
||||
#+begin_src c++
|
||||
// Use this:
|
||||
if (condition)
|
||||
{
|
||||
// some code here
|
||||
}
|
||||
else
|
||||
{
|
||||
// some code here
|
||||
}
|
||||
|
||||
// Instead of
|
||||
if( condition ) {
|
||||
// some code here
|
||||
}
|
||||
else {
|
||||
// some code here
|
||||
}
|
||||
#+end_src
|
||||
|
||||
- Variable names
|
||||
|
||||
#+begin_src c++
|
||||
// Member variables
|
||||
int m_SomeVar; // for stack allocated
|
||||
int* m_pSomeVar; // for heap allocated
|
||||
bool m_bSomeVar; // for booleans
|
||||
|
||||
// Local variables
|
||||
int some_var; // for stack allocated
|
||||
int* someVar; // for heap allocated
|
||||
bool some_var; // for booleans
|
||||
#+end_src
|
||||
|
||||
- Classes and structs
|
||||
|
||||
#+begin_src c++
|
||||
// Use this
|
||||
class cMyClass : public cSomeOtherClass
|
||||
{
|
||||
public:
|
||||
MyClass();
|
||||
~MyClass();
|
||||
private:
|
||||
// private stuff
|
||||
};
|
||||
|
||||
// Instead of
|
||||
class myClass : public someOtherClass {
|
||||
public:
|
||||
MyClass();
|
||||
~MyClass();
|
||||
private:
|
||||
// private stuff
|
||||
};
|
||||
#+end_src
|
||||
|
||||
** Additional Notes
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: additional-notes
|
||||
:END:
|
||||
*** Issue and Pull Request Labels
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: issue-and-pull-request-labels
|
||||
:END:
|
||||
This section lists the labels I use to help me track and manage issues and pull requests.
|
||||
|
||||
**** Issue Labels
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: issue-labels
|
||||
:END:
|
||||
| Label name | Description |
|
||||
|---------------------------+------------------------------------------------------------------------------------------------------------|
|
||||
| =Enhancement= | Issues related to improving the project in some way. |
|
||||
| =Bug= | Confirmed bugs or reports that are very likely to be bugs. |
|
||||
| =Question= | Questions more than bug reports or feature requests (e.g. how do I do X). |
|
||||
| =Feedback= | General feedback more than bug reports or feature requests. |
|
||||
| =Help wanted= | Issues about user(s) needing help. |
|
||||
| =More information needed= | More information needs to be collected about these problems or feature requests (e.g. steps to reproduce). |
|
||||
| =Needs reproduction= | Likely bugs, but haven't been reliably reproduced. |
|
||||
| =Duplicate= | Issues which are duplicates of other issues, i.e. they have been reported before. |
|
||||
|
||||
**** Pull Request Labels
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: pull-request-labels
|
||||
:END:
|
||||
| Label name | Description |
|
||||
|--------------------+------------------------------------------------------------------------------------------|
|
||||
| =Work in progress= | Pull requests which are still being worked on, more changes will follow. |
|
||||
| =Needs review= | Pull requests which need code review, and approval from maintainers. |
|
||||
| =Under review= | Pull requests being reviewed by maintainers. |
|
||||
| =Requires changes= | Pull requests which need to be updated based on review comments and then reviewed again. |
|
||||
| =Needs testing= | Pull requests which need manual testing. |
|
||||
39
README.org
|
|
@ -25,6 +25,8 @@
|
|||
- [[#how-to-run-samplehive][How to run SampleHive?]]
|
||||
- [[#are-there-any-keybindings-for-samplehive][Are there any keybindings for SampleHive?]]
|
||||
- [[#can-i-configure-samplehive][Can I configure SampleHive?]]
|
||||
- [[#how-do-i-contribute-to-the-samplehive][How do I contribute to the SampleHive?]]
|
||||
- [[#want-to-buy-me-a-coffee][Want to BuyMeACoffee?]]
|
||||
|
||||
** What is SampleHive?
|
||||
:PROPERTIES:
|
||||
|
|
@ -46,19 +48,27 @@ SampleHive let's you manage your audio samples in a nice and simple way, just ad
|
|||
:END:
|
||||
On Arch based distributions,
|
||||
|
||||
#+begin_example
|
||||
sudo pacman -S wxgtk3 wxsvg sqlite taglib yaml-cpp
|
||||
#+end_example
|
||||
#+begin_src
|
||||
sudo pacman -S wxgtk3 sqlite taglib yaml-cpp libsndfile spdlog aubio
|
||||
#+end_src
|
||||
|
||||
On Debian, Ubuntu and distributions based the on two,
|
||||
|
||||
#+begin_example
|
||||
sudo apt install libwxbase3.0-dev libwxgtk-media3.0-gtk3-dev libwxgtk3.0-gtk3-dev wx3.0-headers libsqlite3-dev libyaml-cpp-dev libtagc0-dev libtag1-dev libtagc0 libexif-dev libpango1.0-dev
|
||||
#+end_example
|
||||
#+begin_src
|
||||
sudo apt install libwxbase3.0-dev libwxgtk-media3.0-gtk3-dev libwxgtk3.0-gtk3-dev wx3.0-headers libsqlite3-dev libyaml-cpp-dev libtagc0-dev libtag1-dev libtagc0 libexif-dev libpango1.0-dev libsndfile1-dev libspdlog-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev libaubio-dev
|
||||
#+end_src
|
||||
|
||||
You might also need to install =git=, =meson= and =g++= as well, if you don't already have them installed in order to build SampleHive.
|
||||
You might also need to install =git=, =cmake=, =meson= and =g++= as well, if you don't already have them installed in order to build SampleHive.
|
||||
|
||||
/NOTE:/ On Debian and Debian based distributions you also have to install =libwxgtk-media3.0-dev=
|
||||
*NOTE:* On Debian and Debian based distributions you also have to install =libwxgtk-media3.0-dev=
|
||||
|
||||
*Experimental Windows Build*:
|
||||
|
||||
If you want to try out =SampleHive= on =Windows=, you can use the [[https://www.msys2.org/][MSYS2]] environment and [[https://osdn.net/projects/mingw/][MinGW]] compiler for =Windows=. After setting up =MSYS2= and =MinGW= install the following dependencies using the package manager =pacman=.
|
||||
|
||||
#+begin_src
|
||||
pacman -S mingw-w64-x86_64-wxmsw3.1 mingw-w64-x86_64-sqlite mingw-w64-x86_64-taglib mingw-w64-x86_64-yaml-cpp mingw-w64-x86_64-libsndfile mingw-w64-x86_64-spdlog mingw-w64-x86_64-aubio mingw-w64-x86_64-meson mingw-w64-x86_64-cmake git
|
||||
#+end_src
|
||||
|
||||
** How to build SampleHive?
|
||||
:PROPERTIES:
|
||||
|
|
@ -105,3 +115,16 @@ If you didn't provide a prefix, you can find SampleHive in your menu system or r
|
|||
:CUSTOM_ID: can-i-configure-samplehive
|
||||
:END:
|
||||
SampleHive comes with a =config.yaml= file, that is placed under =~/.config/SampleHive/config.yaml=, that you can edit to change some settings for it.
|
||||
|
||||
** How do I contribute to the SampleHive?
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: how-do-i-contribute-to-samplehive
|
||||
:END:
|
||||
Want to help by contributing to =SampleHive=, please check out [[https://gitlab.com/samplehive/sample-hive/-/blob/testing/CONTRIBUTING.org][CONTRIBUTING.org]] for more details.
|
||||
** Want to BuyMeACoffee?
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: want-to-buy-me-a-coffee
|
||||
:END:
|
||||
#+begin_html
|
||||
<a href="https://www.buymeacoffee.com/apoorv569"><img src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=&slug=apoorv569&button_colour=FFDD00&font_colour=000000&font_family=Cookie&outline_colour=000000&coffee_colour=ffffff" /></a>
|
||||
#+end_html
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 280 B |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 415 B |
|
After Width: | Height: | Size: 428 B |
|
After Width: | Height: | Size: 455 B |
|
After Width: | Height: | Size: 445 B |
|
After Width: | Height: | Size: 383 B |
|
After Width: | Height: | Size: 406 B |
|
After Width: | Height: | Size: 263 B |
|
After Width: | Height: | Size: 267 B |
|
Before Width: | Height: | Size: 250 KiB After Width: | Height: | Size: 180 KiB |
|
Before Width: | Height: | Size: 246 KiB After Width: | Height: | Size: 176 KiB |
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 122.88 95.13" style="enable-background:new 0 0 122.88 95.13" xml:space="preserve"><g><path d="M100.95,23.32c0-2.09,1.69-3.78,3.78-3.78c2.09,0,3.78,1.69,3.78,3.78v48.5c0,2.09-1.69,3.78-3.78,3.78 c-2.09,0-3.78-1.69-3.78-3.78V23.32L100.95,23.32z M0,31.82c0-2.09,1.69-3.78,3.78-3.78c2.09,0,3.78,1.69,3.78,3.78v31.49 c0,2.09-1.69,3.78-3.78,3.78C1.69,67.09,0,65.4,0,63.31V31.82L0,31.82z M14.42,23.32c0-2.09,1.69-3.78,3.78-3.78 c2.09,0,3.78,1.69,3.78,3.78v48.5c0,2.09-1.69,3.78-3.78,3.78c-2.09,0-3.78-1.69-3.78-3.78V23.32L14.42,23.32z M28.9,13.9 c0-2.08,1.67-3.76,3.72-3.76c2.06,0,3.72,1.68,3.72,3.76v67.34c0,2.08-1.67,3.76-3.72,3.76c-2.06,0-3.72-1.68-3.72-3.76V13.9 L28.9,13.9z M43.26,3.78c0-2.09,1.69-3.78,3.78-3.78c2.09,0,3.78,1.69,3.78,3.78v87.57c0,2.09-1.69,3.78-3.78,3.78 c-2.09,0-3.78-1.69-3.78-3.78V3.78L43.26,3.78z M86.53,31.82c0-2.09,1.69-3.78,3.78-3.78c2.09,0,3.78,1.69,3.78,3.78v31.49 c0,2.09-1.69,3.78-3.78,3.78c-2.09,0-3.78-1.69-3.78-3.78V31.82L86.53,31.82z M72.11,23.32c0-2.09,1.69-3.78,3.78-3.78 c2.09,0,3.78,1.69,3.78,3.78v48.5c0,2.09-1.69,3.78-3.78,3.78c-2.09,0-3.78-1.69-3.78-3.78V23.32L72.11,23.32z M57.74,13.9 c0-2.08,1.67-3.76,3.72-3.76c2.06,0,3.72,1.68,3.72,3.76v67.34c0,2.08-1.67,3.76-3.72,3.76c-2.06,0-3.72-1.68-3.72-3.76V13.9 L57.74,13.9z M115.43,13.9c0-2.08,1.67-3.76,3.72-3.76c2.06,0,3.72,1.68,3.72,3.76v67.34c0,2.08-1.67,3.76-3.72,3.76 c-2.06,0-3.72-1.68-3.72-3.76V13.9L115.43,13.9z"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 1.6 KiB |
|
|
@ -17,13 +17,52 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
project('SampleHive', 'cpp',
|
||||
version : 'v0.8.4_alpha.1',
|
||||
project('SampleHive',
|
||||
'cpp',
|
||||
version : 'v0.9.0_alpha.1',
|
||||
license : 'GPL v3',
|
||||
default_options : ['warning_level=1',
|
||||
'cpp_std=c++11'])
|
||||
meson_version: '>= 1.5.2',
|
||||
default_options : ['warning_level=2',
|
||||
'buildtype=debugoptimized',
|
||||
'b_lto=true',
|
||||
'b_lto_threads=2',
|
||||
'cpp_std=gnu++20'])
|
||||
|
||||
# Create configuration data
|
||||
config_data = configuration_data()
|
||||
|
||||
# Save project information
|
||||
meson_src_root = meson.current_source_dir()
|
||||
meson_build_root = meson.current_build_dir()
|
||||
|
||||
project_name = meson.project_name()
|
||||
project_license = meson.project_license()
|
||||
project_version = meson.project_version()
|
||||
project_author = 'Apoorv'
|
||||
project_copyright_years = '2020-2025'
|
||||
project_description = 'A simple, modern audio sample browser/manager for GNU/Linux.'
|
||||
project_website = 'http://samplehive.gitlab.io/website'
|
||||
|
||||
build_type = get_option('buildtype')
|
||||
|
||||
host_sys = host_machine.system()
|
||||
|
||||
cpp_compiler_id = meson.get_compiler('cpp').get_id()
|
||||
cpp_compiler_version = meson.get_compiler('cpp').version()
|
||||
|
||||
config_data.set_quoted('PROJECT_NAME', project_name)
|
||||
config_data.set_quoted('PROJECT_LICENSE', project_license)
|
||||
config_data.set_quoted('PROJECT_VERSION', project_version)
|
||||
config_data.set_quoted('PROJECT_AUTHOR', project_author)
|
||||
config_data.set_quoted('PROJECT_COPYRIGHT_YEARS', project_copyright_years)
|
||||
config_data.set_quoted('PROJECT_DESCRIPTION', project_description)
|
||||
config_data.set_quoted('PROJECT_WEBSITE', project_website)
|
||||
config_data.set_quoted('BUILD_TYPE', build_type)
|
||||
config_data.set_quoted('HOST_MACHINE', host_sys)
|
||||
config_data.set_quoted('MESON_SRC_ROOT', meson_src_root)
|
||||
config_data.set_quoted('MESON_BUILD_ROOT', meson_build_root)
|
||||
config_data.set_quoted('CPP_COMPILER', cpp_compiler_id)
|
||||
config_data.set_quoted('CPP_COMPILER_VERSION', cpp_compiler_version)
|
||||
|
||||
# Save important directories
|
||||
prefix = get_option('prefix')
|
||||
|
|
@ -32,59 +71,277 @@ libdir = prefix / get_option('libdir')
|
|||
datadir = prefix / get_option('datadir')
|
||||
samplehive_datadir = datadir / 'SampleHive'
|
||||
|
||||
# Create configuration data
|
||||
config_data = configuration_data()
|
||||
config_data.set_quoted('PREFIX', prefix)
|
||||
config_data.set_quoted('BINDIR', bindir)
|
||||
config_data.set_quoted('LIBDIR', libdir)
|
||||
config_data.set_quoted('DATADIR', datadir)
|
||||
config_data.set_quoted('SAMPLEHIVE_DATADIR', samplehive_datadir)
|
||||
|
||||
# Create samplehive-config.h based on configuration
|
||||
config_h = configure_file(
|
||||
output: 'SampleHiveConfig.hpp',
|
||||
configuration: config_data,
|
||||
)
|
||||
if build_type == 'debug' or build_type == 'debugoptimized'
|
||||
config_data.set('SH_BUILD_DEBUG', 1)
|
||||
elif build_type == 'release'
|
||||
config_data.set('SH_BUILD_RELEASE', 1)
|
||||
endif
|
||||
|
||||
# Import CMake
|
||||
cmake = import('cmake')
|
||||
|
||||
# Check which platform the build is for and set the appropriate GUI toolkit
|
||||
wx_toolkit = ''
|
||||
|
||||
if host_sys == 'linux'
|
||||
wx_toolkit = 'gtk3'
|
||||
elif host_sys == 'windows'
|
||||
wx_toolkit = 'msw'
|
||||
elif host_sys == 'darwin'
|
||||
wx_toolkit = 'osx_cocoa'
|
||||
endif
|
||||
|
||||
wx_opts = cmake.subproject_options()
|
||||
wx_opts.add_cmake_defines({'CMAKE_POSITION_INDEPENDENT_CODE': 'ON',
|
||||
'CMAKE_INSTALL_PREFIX': prefix,
|
||||
'CMAKE_BUILD_TYPE': 'Release',
|
||||
'wxBUILD_SHARED': 'OFF',
|
||||
'wxBUILD_MONOLITHIC': 'OFF',
|
||||
'wxBUILD_BENCHMARKS': 'OFF',
|
||||
'wxBUILD_PRECOMP': 'OFF',
|
||||
'wxBUILD_TESTS': 'OFF',
|
||||
'wxBUILD_SAMPLES': 'OFF',
|
||||
'wxBUILD_DEMOS': 'OFF',
|
||||
'wxBUILD_COMPATIBILITY': '3.2',
|
||||
'wxBUILD_TOOLKIT': wx_toolkit,
|
||||
'wxUSE_UNICODE': 'ON',
|
||||
'wxUSE_GUI': 'ON',
|
||||
'wxUSE_AUI': 'OFF',
|
||||
'wxUSE_XML': 'OFF',
|
||||
'wxUSE_XRC': 'ON',
|
||||
'wxUSE_HTML': 'ON',
|
||||
'wxUSE_QA': 'ON',
|
||||
'wxUSE_PROPGRID': 'OFF',
|
||||
'wxUSE_RIBBON': 'OFF',
|
||||
'wxUSE_MDI': 'OFF',
|
||||
'wxUSE_MDI_ARCHITECTURE': 'OFF',
|
||||
'wxUSE_POSTSCRIPT': 'ON',
|
||||
'wxUSE_RICHTEXT': 'OFF',
|
||||
'wxUSE_WEBVIEW': 'OFF',
|
||||
'wxUSE_LIBSDL': 'OFF',
|
||||
'wxUSE_MEDIACTRL': 'ON'})
|
||||
|
||||
spdlog_opts = cmake.subproject_options()
|
||||
spdlog_opts.add_cmake_defines({'CMAKE_POSITION_INDEPENDENT_CODE': 'ON',
|
||||
'CMAKE_INSTALL_PREFIX': prefix,
|
||||
'CMAKE_BUILD_TYPE': 'Release',
|
||||
'SPDLOG_USE_STD_FORMAT': 'ON',
|
||||
'SPDLOG_BUILD_EXAMPLE': 'OFF',
|
||||
'SPDLOG_BUILD_EXAMPLE_HO': 'OFF',
|
||||
'SPDLOG_BUILD_TESTS': 'OFF',
|
||||
'SPDLOG_BUILD_TESTS_HO': 'OFF',
|
||||
'SPDLOG_BUILD_BENCH': 'OFF'})
|
||||
|
||||
taglib_opts = cmake.subproject_options()
|
||||
taglib_opts.add_cmake_defines({'CMAKE_POSITION_INDEPENDENT_CODE': 'ON',
|
||||
'CMAKE_INSTALL_PREFIX': prefix,
|
||||
'CMAKE_BUILD_TYPE': 'Release'})
|
||||
|
||||
yaml_opts = cmake.subproject_options()
|
||||
yaml_opts.add_cmake_defines({'CMAKE_POSITION_INDEPENDENT_CODE': 'ON',
|
||||
'CMAKE_INSTALL_PREFIX': prefix,
|
||||
'CMAKE_BUILD_TYPE': 'Release',
|
||||
'YAML_BUILD_SHARED_LIBS': 'ON',
|
||||
'YAML_CPP_BUILD_TESTS': 'OFF',
|
||||
'YAML_CPP_BUILD_CONTRIB': 'ON',
|
||||
'YAML_CPP_BUILD_TOOLS': 'ON'})
|
||||
|
||||
snd_opts = cmake.subproject_options()
|
||||
|
||||
snd_shared = ''
|
||||
|
||||
if host_sys == 'windows'
|
||||
snd_shared = 'OFF'
|
||||
else
|
||||
snd_shared = 'ON'
|
||||
endif
|
||||
|
||||
snd_opts.add_cmake_defines({'CMAKE_POSITION_INDEPENDENT_CODE': 'ON',
|
||||
'CMAKE_INSTALL_PREFIX': prefix,
|
||||
'CMAKE_BUILD_TYPE': 'Release',
|
||||
'BUILD_SHARED_LIBS': snd_shared,
|
||||
'BUILD_PROGRAMS': 'OFF',
|
||||
'BUILD_EXAMPLES': 'OFF',
|
||||
'BUILD_TESTING': 'OFF',
|
||||
'ENABLE_EXTERNAL_LIBS': 'ON',
|
||||
'ENABLE_MPEG': 'ON'})
|
||||
|
||||
# Disable link time optimization if host is Windows
|
||||
if host_sys == 'windows'
|
||||
wx_opts.set_override_option('b_lto', 'false')
|
||||
taglib_opts.set_override_option('b_lto', 'false')
|
||||
yaml_opts.set_override_option('b_lto', 'false')
|
||||
snd_opts.set_override_option('b_lto', 'false')
|
||||
endif
|
||||
|
||||
# Source files to be compiled
|
||||
src = [
|
||||
|
||||
'src/App.cpp',
|
||||
'src/MainFrame.cpp',
|
||||
'src/SettingsDialog.cpp',
|
||||
'src/TagEditorDialog.cpp',
|
||||
'src/Database.cpp',
|
||||
'src/Sample.cpp',
|
||||
'src/Serialize.cpp',
|
||||
'src/Tags.cpp',
|
||||
|
||||
'src/GUI/MainFrame.cpp',
|
||||
'src/GUI/TransportControls.cpp',
|
||||
'src/GUI/WaveformViewer.cpp',
|
||||
'src/GUI/Notebook.cpp',
|
||||
'src/GUI/DirectoryBrowser.cpp',
|
||||
'src/GUI/Hives.cpp',
|
||||
'src/GUI/Trash.cpp',
|
||||
'src/GUI/ListCtrl.cpp',
|
||||
'src/GUI/SearchBar.cpp',
|
||||
'src/GUI/InfoBar.cpp',
|
||||
'src/GUI/Library.cpp',
|
||||
|
||||
'src/GUI/Dialogs/Settings.cpp',
|
||||
'src/GUI/Dialogs/TagEditor.cpp',
|
||||
|
||||
'src/Database/Database.cpp',
|
||||
|
||||
'src/Utility/Sample.cpp',
|
||||
'src/Utility/Serialize.cpp',
|
||||
'src/Utility/Tags.cpp',
|
||||
'src/Utility/Event.cpp',
|
||||
'src/Utility/Signal.cpp',
|
||||
'src/Utility/Log.cpp',
|
||||
'src/Utility/Utils.cpp',
|
||||
|
||||
]
|
||||
|
||||
wxconfig = find_program(['wx-config-gtk3', 'wx-config'])
|
||||
wx_modules = ['media', 'std']
|
||||
include_dirs = include_directories('src')
|
||||
|
||||
# Static link C and CXX libs if platform is windows
|
||||
link_args = []
|
||||
|
||||
if host_sys == 'windows'
|
||||
link_args += ['-static-libgcc', '-static-libstdc++']
|
||||
endif
|
||||
|
||||
# Dependencies
|
||||
wx = dependency('wxwidgets', version: '>=3.2.8', required: true)
|
||||
|
||||
wx_cxx_flags = []
|
||||
wx_libs = []
|
||||
|
||||
if not wx.found()
|
||||
wx_subproject = cmake.subproject('wxwidgets', options: wx_opts)
|
||||
wx_media = wx_subproject.dependency('wxmedia')
|
||||
wx_core = wx_subproject.dependency('wxcore')
|
||||
wx_base = wx_subproject.dependency('wxbase')
|
||||
wx = [wx_media, wx_core, wx_base]
|
||||
|
||||
if host_sys == 'windows'
|
||||
win = import('windows')
|
||||
wx_inc = wx_subproject.include_directories('wxbase')
|
||||
rc_file = win.compile_resources('src/GUI/Resources.rc', include_directories: wx_inc)
|
||||
|
||||
src += rc_file
|
||||
endif
|
||||
else
|
||||
wxconfig = find_program(['wx-config', 'wx-config-gtk3', 'wx-config-3.2'])
|
||||
wx_modules = ['media', 'std']
|
||||
|
||||
foreach module : wx_modules
|
||||
wx_cxx_flags += run_command(wxconfig, '--cxxflags', module).stdout().strip().split()
|
||||
wx_libs += run_command(wxconfig, '--libs', module).stdout().strip().split()
|
||||
wx_cxx_flags += run_command(wxconfig, '--cxxflags', module, capture: true, check: false).stdout().strip().split()
|
||||
wx_libs += run_command(wxconfig, '--libs', module, capture: true, check: false).stdout().strip().split()
|
||||
endforeach
|
||||
endif
|
||||
|
||||
# Dependencies
|
||||
wx = dependency('wxwidgets', version: '>=3.0.4')
|
||||
taglib = dependency('taglib', version: '>=1.11')
|
||||
sqlite3 = dependency('sqlite3')
|
||||
yaml = dependency('yaml-cpp')
|
||||
taglib = dependency('taglib', version: '>=1.12', required: true)
|
||||
|
||||
install_subdir(
|
||||
'assets',
|
||||
if not taglib.found()
|
||||
taglib_subproject = cmake.subproject('taglib', options: taglib_opts)
|
||||
taglib = taglib_subproject.dependency('tag')
|
||||
else
|
||||
config_data.set('USE_SYSTEM_INCLUDE_PATH', 1)
|
||||
endif
|
||||
|
||||
sqlite3 = dependency('sqlite3', version: '>=3.45.1', required: true)
|
||||
|
||||
if not sqlite3.found()
|
||||
sqlite3_subproject = subproject('sqlite3')
|
||||
libsqlite3 = sqlite3_subproject.get_variable('libsqlite3')
|
||||
sqlite3 = declare_dependency(link_with: libsqlite3)
|
||||
endif
|
||||
|
||||
yaml = dependency('yaml-cpp', version: '>=0.8.0', required: true)
|
||||
|
||||
if not yaml.found()
|
||||
yaml_subproject = cmake.subproject('yaml-cpp', options: yaml_opts)
|
||||
yaml = yaml_subproject.dependency('yaml-cpp')
|
||||
endif
|
||||
|
||||
snd = dependency('sndfile', version: '>=1.2.0', required: true)
|
||||
|
||||
if not snd.found()
|
||||
snd_subproject = cmake.subproject('libsndfile', options: snd_opts)
|
||||
snd = snd_subproject.dependency('sndfile')
|
||||
endif
|
||||
|
||||
spdlog = dependency('spdlog', version: '>=1.12.0', required: true)
|
||||
|
||||
if not spdlog.found()
|
||||
spdlog_subproject = cmake.subproject('spdlog', options: spdlog_opts)
|
||||
spdlog = spdlog_subproject.dependency('spdlog')
|
||||
endif
|
||||
|
||||
aubio = dependency('aubio', version: '>=0.4.9', required: true)
|
||||
|
||||
if not aubio.found()
|
||||
aubio_subproject = subproject('aubio')
|
||||
aubio = aubio_subproject.get_variable('aubio_dep')
|
||||
endif
|
||||
|
||||
# Create SampleHiveConfig.hpp based on configuration
|
||||
config = configure_file(output: 'SampleHiveConfig.hpp',
|
||||
configuration: config_data,)
|
||||
|
||||
install_subdir('assets',
|
||||
install_dir: samplehive_datadir,
|
||||
exclude_directories: 'screenshots'
|
||||
)
|
||||
exclude_directories: 'screenshots',
|
||||
strip_directory: true)
|
||||
|
||||
executable('SampleHive',
|
||||
sources: src,
|
||||
cpp_args: [wx_cxx_flags],
|
||||
link_args: [wx_libs],
|
||||
dependencies: [wx, taglib, sqlite3, yaml],
|
||||
install: true)
|
||||
link_args: [wx_libs, link_args],
|
||||
include_directories : include_dirs,
|
||||
dependencies: [wx, taglib, sqlite3, yaml, snd, spdlog, aubio],
|
||||
install: true,
|
||||
install_rpath: prefix / 'lib')
|
||||
|
||||
summary(
|
||||
{
|
||||
'Build type': build_type,
|
||||
'Optimization': get_option('optimization'),
|
||||
'Link time optimization': get_option('b_lto'),
|
||||
'Warning level': get_option('warning_level'),
|
||||
'Host system': host_sys,
|
||||
},
|
||||
section: 'General')
|
||||
|
||||
summary(
|
||||
{
|
||||
'prefix': prefix,
|
||||
'bindir': bindir,
|
||||
'libdir': libdir,
|
||||
'datadir': datadir,
|
||||
'samplehive_datadir': samplehive_datadir,
|
||||
},
|
||||
section: 'Directories')
|
||||
|
||||
summary(
|
||||
{
|
||||
'Project name': project_name,
|
||||
'Project license': project_license,
|
||||
'Project version': project_version,
|
||||
'Project author': project_author,
|
||||
'Project copyright years': project_copyright_years,
|
||||
'Project description': project_description,
|
||||
'Project website': project_website,
|
||||
},
|
||||
section: 'Project')
|
||||
|
|
|
|||
140
src/App.cpp
|
|
@ -19,47 +19,159 @@
|
|||
*/
|
||||
|
||||
#include "App.hpp"
|
||||
#include "SampleHiveConfig.hpp"
|
||||
#include "Utility/Paths.hpp"
|
||||
#include "Utility/Log.hpp"
|
||||
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/defs.h>
|
||||
#include <wx/filefn.h>
|
||||
#include <wx/fswatcher.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/splash.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/imagpng.h>
|
||||
|
||||
#define SPLASH_LOGO SAMPLEHIVE_DATADIR "/assets/logo/logo-samplehive_768x432.png"
|
||||
wxIMPLEMENT_APP(cApp);
|
||||
|
||||
wxIMPLEMENT_APP(App);
|
||||
|
||||
App::App()
|
||||
cApp::cApp()
|
||||
{
|
||||
|
||||
// Initialize the logger
|
||||
SampleHive::cLog::InitLogger("SampleHive");
|
||||
}
|
||||
|
||||
App::~App()
|
||||
cApp::~cApp()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool App::OnInit()
|
||||
bool cApp::OnInit()
|
||||
{
|
||||
if (!wxApp::OnInit())
|
||||
return false;
|
||||
|
||||
m_Frame = new MainFrame();
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
wxLog::AddTraceMask("EventSource");
|
||||
wxLog::AddTraceMask(wxTRACE_FSWATCHER);
|
||||
|
||||
// Add image handler for PNG
|
||||
wxImage::AddHandler(new wxPNGHandler);
|
||||
|
||||
m_pFrame = new cMainFrame();
|
||||
|
||||
wxBitmap bitmap;
|
||||
wxSplashScreen* splash;
|
||||
|
||||
if (bitmap.LoadFile(SPLASH_LOGO, wxBITMAP_TYPE_PNG))
|
||||
{
|
||||
splash = new wxSplashScreen(bitmap,
|
||||
m_pSplash = new wxSplashScreen(bitmap,
|
||||
wxSPLASH_CENTRE_ON_SCREEN | wxSPLASH_TIMEOUT,
|
||||
2000, NULL, -1, wxDefaultPosition, wxDefaultSize,
|
||||
wxBORDER_SIMPLE | wxSTAY_ON_TOP);
|
||||
}
|
||||
|
||||
if (!serializer.DeserializeShowSplash())
|
||||
m_pSplash->Hide();
|
||||
else
|
||||
m_pSplash->Show();
|
||||
|
||||
wxYield();
|
||||
|
||||
m_Frame->Show(true);
|
||||
m_pFrame->Show(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
void cApp::OnInitCmdLine(wxCmdLineParser& parser)
|
||||
{
|
||||
wxApp::OnInitCmdLine(parser);
|
||||
|
||||
parser.AddSwitch("v", "version", "Shows the application version", 0);
|
||||
parser.AddSwitch("r", "reset", "Reset app data", 0);
|
||||
parser.Parse(true);
|
||||
}
|
||||
|
||||
bool cApp::OnCmdLineParsed(wxCmdLineParser& parser)
|
||||
{
|
||||
if (!wxApp::OnCmdLineParsed(parser))
|
||||
return false;
|
||||
|
||||
if (parser.Found("version"))
|
||||
{
|
||||
std::cout << PROJECT_NAME << ' ' << PROJECT_VERSION << std::endl;
|
||||
std::cout <<
|
||||
"\nCopyright (C) 2021 Apoorv Singh"
|
||||
"\nA simple, modern audio sample browser/manager for GNU/Linux."
|
||||
"\n"
|
||||
"\nThis file is a part of SampleHive"
|
||||
"\n"
|
||||
"\nSampleHive is free software: you can redistribute it and/or modify"
|
||||
"\nit under the terms of the GNU General Public License as published by"
|
||||
"\nthe Free Software Foundation, either version 3 of the License, or"
|
||||
"\n(at your option) any later version."
|
||||
"\n"
|
||||
"\nSampleHive is distributed in the hope that it will be useful,"
|
||||
"\nbut WITHOUT ANY WARRANTY; without even the implied warranty of"
|
||||
"\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"
|
||||
"\nGNU General Public License for more details."
|
||||
"\n"
|
||||
"\nYou should have received a copy of the GNU General Public License"
|
||||
"\nalong with this program. If not, see <https://www.gnu.org/licenses/>."
|
||||
<< std::endl;
|
||||
return false;
|
||||
}
|
||||
else if (parser.Found("reset"))
|
||||
{
|
||||
char ans;
|
||||
|
||||
std::cout << "Are you sure you want clear all app data? [y/N] ";
|
||||
std::cin >> ans;
|
||||
|
||||
if (ans == 'y' || ans == 'Y')
|
||||
{
|
||||
if (!wxFileExists(static_cast<std::string>(CONFIG_FILEPATH)))
|
||||
{
|
||||
SH_LOG_ERROR("Error! File {} doesn't exist.", static_cast<std::string>(CONFIG_FILEPATH));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool config_is_deleted = wxRemoveFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (config_is_deleted)
|
||||
SH_LOG_INFO("Deleted {}", static_cast<std::string>(CONFIG_FILEPATH));
|
||||
else
|
||||
SH_LOG_ERROR("Could not delete {}", static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (!wxFileExists(static_cast<std::string>(DATABASE_FILEPATH)))
|
||||
{
|
||||
SH_LOG_ERROR("Error! File {} doesn't exist.", static_cast<std::string>(DATABASE_FILEPATH));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool db_is_deleted = wxRemoveFile(static_cast<std::string>(DATABASE_FILEPATH));
|
||||
|
||||
if (db_is_deleted)
|
||||
SH_LOG_INFO("Deleted {}", static_cast<std::string>(DATABASE_FILEPATH));
|
||||
else
|
||||
SH_LOG_ERROR("Could not delete {}", static_cast<std::string>(DATABASE_FILEPATH));
|
||||
|
||||
if (config_is_deleted && db_is_deleted)
|
||||
SH_LOG_INFO("Successfully cleared app data");
|
||||
else
|
||||
SH_LOG_ERROR("Error! Could not clear app data");
|
||||
|
||||
return false;
|
||||
}
|
||||
else if (ans == 'n' || ans == 'N')
|
||||
return false;
|
||||
else
|
||||
{
|
||||
SH_LOG_ERROR("Unknown option '{}' please select a correct option", ans);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void cApp::OnEventLoopEnter(wxEventLoopBase* event)
|
||||
{
|
||||
if (m_pFrame->CreateWatcherIfNecessary())
|
||||
SH_LOG_INFO("Filesystem watcher created sucessfully");
|
||||
}
|
||||
|
|
|
|||
22
src/App.hpp
|
|
@ -20,19 +20,25 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "GUI/MainFrame.hpp"
|
||||
|
||||
#include <wx/app.h>
|
||||
#include <wx/cmdline.h>
|
||||
#include <wx/splash.h>
|
||||
|
||||
#include "MainFrame.hpp"
|
||||
|
||||
class App : public wxApp
|
||||
class cApp : public wxApp
|
||||
{
|
||||
public:
|
||||
App();
|
||||
~App();
|
||||
|
||||
private:
|
||||
MainFrame* m_Frame = nullptr;
|
||||
cApp();
|
||||
~cApp();
|
||||
|
||||
private:
|
||||
virtual bool OnInit();
|
||||
virtual void OnEventLoopEnter(wxEventLoopBase* event);
|
||||
virtual void OnInitCmdLine(wxCmdLineParser& parser);
|
||||
virtual bool OnCmdLineParsed(wxCmdLineParser& parser);
|
||||
|
||||
private:
|
||||
wxSplashScreen* m_pSplash = nullptr;
|
||||
cMainFrame* m_pFrame = nullptr;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,113 +0,0 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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_Hives,
|
||||
BC_DirCtrl,
|
||||
BC_Library,
|
||||
BC_Search,
|
||||
BC_MediaCtrl,
|
||||
BC_Trash,
|
||||
BC_RestoreTrashedItem,
|
||||
BC_HiveAdd,
|
||||
BC_HiveRemove,
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Setting dialog controls
|
||||
SD_BrowseConfigDir,
|
||||
SD_BrowseDatabaseDir,
|
||||
SD_AutoImport,
|
||||
SD_ShowFileExtension,
|
||||
SD_BrowseAutoImportDir,
|
||||
SD_FontType,
|
||||
SD_FontSize,
|
||||
SD_FontBrowseButton,
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// App Menu items
|
||||
MN_AddFile,
|
||||
MN_AddDirectory,
|
||||
MN_ToggleExtension,
|
||||
MN_ToggleMenuBar,
|
||||
MN_ToggleStatusBar,
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Library Menu items
|
||||
MN_FavoriteSample,
|
||||
MN_DeleteSample,
|
||||
MN_TrashSample,
|
||||
MN_EditTagSample,
|
||||
MN_OpenFile,
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Library Column Header Menu items
|
||||
MN_ColumnFavorite,
|
||||
MN_ColumnFilename,
|
||||
MN_ColumnSamplePack,
|
||||
MN_ColumnType,
|
||||
MN_ColumnChannels,
|
||||
MN_ColumnLength,
|
||||
MN_ColumnSampleRate,
|
||||
MN_ColumnBitrate,
|
||||
MN_ColumnPath,
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Hives Menu items
|
||||
MN_RenameHive,
|
||||
MN_DeleteHive,
|
||||
MN_RemoveSample,
|
||||
MN_FilterLibrary,
|
||||
MN_ShowInLibrary,
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Trash Menu items
|
||||
MN_DeleteTrash,
|
||||
MN_RestoreTrashedItem,
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Edit tags dialog controls
|
||||
ET_TitleCheck,
|
||||
ET_ArtistCheck,
|
||||
ET_AlbumCheck,
|
||||
ET_GenreCheck,
|
||||
ET_CommentsCheck,
|
||||
ET_TypeCheck,
|
||||
ET_CustomTag,
|
||||
};
|
||||
1477
src/Database.cpp
112
src/Database.hpp
|
|
@ -1,112 +0,0 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#include <wx/dataview.h>
|
||||
#include <wx/infobar.h>
|
||||
#include <wx/treebase.h>
|
||||
#include <wx/treectrl.h>
|
||||
#include <wx/vector.h>
|
||||
#include <wx/variant.h>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include "Sample.hpp"
|
||||
|
||||
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:
|
||||
// -------------------------------------------------------------------
|
||||
// Create the table
|
||||
void CreateTableSamples(const std::string& dbPath);
|
||||
void CreateTableHives(const std::string& dbPath);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Insert into database
|
||||
void InsertIntoSamples(const std::string& dbPath, std::vector<Sample>);
|
||||
void InsertIntoHives(const std::string& dbPath, const std::string& hiveName);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Update database
|
||||
void UpdateFavoriteColumn(const std::string& dbPath, const std::string& filename, int value);
|
||||
void UpdateHive(const std::string& dbPath, const std::string& hiveOldName, const std::string& hiveNewName);
|
||||
void UpdateHiveName(const std::string& dbPath, const std::string& filename, const std::string& hiveName);
|
||||
void UpdateTrashColumn(const std::string& dbPath, const std::string& filename, int value);
|
||||
void UpdateSamplePack(const std::string& dbPath, const std::string& filename, const std::string& samplePack);
|
||||
void UpdateSampleType(const std::string& dbPath, const std::string& filename, const std::string& type);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Get from database
|
||||
int GetFavoriteColumnValueByFilename(const std::string& dbPath, const std::string& filename);
|
||||
std::string GetHiveByFilename(const std::string& dbPath, const std::string& filename);
|
||||
std::string GetSamplePathByFilename(const std::string& dbPath, const std::string& filename);
|
||||
std::string GetSampleFileExtension(const std::string& dbPath, const std::string& filename);
|
||||
std::string GetSampleType(const std::string& dbPath, const std::string& filename);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Check database
|
||||
bool IsTrashed(const std::string& dbPath, const std::string& filename);
|
||||
wxArrayString CheckDuplicates(const std::string& dbPath, const wxArrayString& files);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Remove from database
|
||||
void RemoveSampleFromDatabase(const std::string& dbPath, const std::string& filename);
|
||||
void RemoveHiveFromDatabase(const std::string& dbPath, const std::string& hiveName);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
wxVector<wxVector<wxVariant>>
|
||||
// LoadDatabase(wxVector<wxVector<wxVariant>> &vecSet,
|
||||
// wxTreeCtrl& favorite_tree, wxTreeItemId& favorite_item,
|
||||
// wxTreeCtrl& trash_tree, wxTreeItemId& trash_item, bool show_extension);
|
||||
LoadSamplesDatabase(const std::string& dbPath, wxVector<wxVector<wxVariant>>& vecSet,
|
||||
wxDataViewTreeCtrl& favorite_tree, wxDataViewItem& favorite_item,
|
||||
wxTreeCtrl& trash_tree, wxTreeItemId& trash_item, bool show_extension,
|
||||
const std::string& icon_star_filled, const std::string& icon_star_emtpy);
|
||||
void LoadHivesDatabase(const std::string& dbPath, wxDataViewTreeCtrl& favorite_tree);
|
||||
wxVector<wxVector<wxVariant>>
|
||||
RestoreFromTrashByFilename(const std::string& dbPath, const std::string& filename,
|
||||
wxVector<wxVector<wxVariant>>& vecSet, bool show_extension,
|
||||
const std::string& icon_star_filled, const std::string& icon_star_empty);
|
||||
wxVector<wxVector<wxVariant>>
|
||||
FilterDatabaseBySampleName(const std::string& dbPath, wxVector<wxVector<wxVariant>>& sampleVec,
|
||||
const std::string& sampleName, bool show_extension,
|
||||
const std::string& icon_star_filled, const std::string& icon_star_empty);
|
||||
wxVector<wxVector<wxVariant>>
|
||||
FilterDatabaseByHiveName(const std::string& dbPath, wxVector<wxVector<wxVariant>>& sampleVec,
|
||||
const std::string& hiveName, bool show_extension,
|
||||
const std::string& icon_star_filled, const std::string& icon_star_empty);
|
||||
};
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "Utility/Sample.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#include <wx/dataview.h>
|
||||
#include <wx/infobar.h>
|
||||
#include <wx/treebase.h>
|
||||
#include <wx/treectrl.h>
|
||||
#include <wx/vector.h>
|
||||
#include <wx/variant.h>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
class cDatabase
|
||||
{
|
||||
public:
|
||||
cDatabase();
|
||||
~cDatabase();
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
sqlite3* m_pDatabase = nullptr;
|
||||
int rc;
|
||||
char* m_pErrMsg = nullptr;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
void OpenDatabase();
|
||||
void CloseDatabase();
|
||||
|
||||
void OpenTemporaryDatabase();
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
// Create the table
|
||||
void CreateTableSamples();
|
||||
void CreateTableHives();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Insert into database
|
||||
void InsertIntoSamples(const std::vector<Sample>&);
|
||||
void InsertIntoHives(const std::string& hiveName);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Update database
|
||||
void UpdateFavoriteColumn(const std::string& filename, int value);
|
||||
void UpdateHive(const std::string& hiveOldName, const std::string& hiveNewName);
|
||||
void UpdateHiveName(const std::string& filename, const std::string& hiveName);
|
||||
void UpdateTrashColumn(const std::string& filename, int value);
|
||||
void UpdateSamplePack(const std::string& filename, const std::string& samplePack);
|
||||
void UpdateSampleType(const std::string& filename, const std::string& type);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Get from database
|
||||
int GetFavoriteColumnValueByFilename(const std::string& filename);
|
||||
std::string GetHiveByFilename(const std::string& filename);
|
||||
std::string GetSamplePathByFilename(const std::string& filename);
|
||||
std::string GetSampleFileExtension(const std::string& filename);
|
||||
std::string GetSampleType(const std::string& filename);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Check database
|
||||
bool IsTrashed(const std::string& filename);
|
||||
wxArrayString CheckDuplicates(const wxArrayString& files);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Remove from database
|
||||
void RemoveSampleFromDatabase(const std::string& filename);
|
||||
void RemoveHiveFromDatabase(const std::string& hiveName);
|
||||
|
||||
void DeleteAllSamples();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
wxVector<wxVector<wxVariant>>
|
||||
LoadSamplesDatabase(wxDataViewTreeCtrl& favorite_tree, wxDataViewItem& favorite_item,
|
||||
wxTreeCtrl& trash_tree, wxTreeItemId& trash_item, bool show_extension,
|
||||
const std::string& icon_star_filled, const std::string& icon_star_emtpy);
|
||||
void LoadHivesDatabase(wxDataViewTreeCtrl& favorite_tree);
|
||||
wxVector<wxVector<wxVariant>>
|
||||
RestoreFromTrashByFilename(const std::string& filename,
|
||||
wxVector<wxVector<wxVariant>>& vecSet, bool show_extension,
|
||||
const std::string& icon_star_filled, const std::string& icon_star_empty);
|
||||
wxVector<wxVector<wxVariant>>
|
||||
FilterDatabaseBySampleName(const std::string& sampleName, bool show_extension,
|
||||
const std::string& icon_star_filled, const std::string& icon_star_empty);
|
||||
wxVector<wxVector<wxVariant>>
|
||||
FilterDatabaseByHiveName(const std::string& hiveName, bool show_extension,
|
||||
const std::string& icon_star_filled, const std::string& icon_star_empty);
|
||||
};
|
||||
|
|
@ -0,0 +1,534 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "GUI/Dialogs/Settings.hpp"
|
||||
#include "Utility/ControlIDs.hpp"
|
||||
#include "Utility/Log.hpp"
|
||||
#include "Utility/Paths.hpp"
|
||||
#include "Utility/Serialize.hpp"
|
||||
|
||||
#include <wx/defs.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/stringimpl.h>
|
||||
#include <wx/settings.h>
|
||||
|
||||
cSettings::cSettings(wxWindow *window)
|
||||
: wxDialog(window, wxID_ANY, "cSettings", wxDefaultPosition,
|
||||
wxSize(720, 300), wxDEFAULT_DIALOG_STYLE | wxSTAY_ON_TOP),
|
||||
m_pWindow(window)
|
||||
{
|
||||
m_pPanel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
m_pMainSizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_pNotebookSizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_pButtonSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
m_pNotebook = new wxNotebook(m_pPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, _T("NOTEBOOK"));
|
||||
|
||||
m_pDisplaySettingPanel = new wxPanel(m_pNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
m_pDisplayTopSizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_pDisplayFontSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_pWaveformColourSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
wxString fontChoices[] = { "System default" };
|
||||
|
||||
m_pFontTypeText = new wxStaticText(m_pDisplaySettingPanel, wxID_ANY, "Font", wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_pFontType = new wxChoice(m_pDisplaySettingPanel, SampleHive::ID::SD_FontType,
|
||||
wxDefaultPosition, wxDefaultSize, 1, fontChoices, 0);
|
||||
m_pFontType->SetSelection(0);
|
||||
m_pFontSize = new wxSpinCtrl(m_pDisplaySettingPanel, SampleHive::ID::SD_FontSize, "Default", wxDefaultPosition, wxDefaultSize);
|
||||
m_pFontSize->SetValue(window->GetFont().GetPointSize());
|
||||
m_pFontBrowseButton = new wxButton(m_pDisplaySettingPanel, SampleHive::ID::SD_FontBrowseButton, "Select font",
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_pWaveformColourLabel = new wxStaticText(m_pDisplaySettingPanel, wxID_ANY, "Waveform colour",
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_pWaveformColourPickerCtrl = new wxColourPickerCtrl(m_pDisplaySettingPanel, SampleHive::ID::SD_WaveformColourPickerCtrl,
|
||||
serializer.DeserializeWaveformColour(),
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
wxCLRP_DEFAULT_STYLE);
|
||||
m_pShowSplashCheck = new wxCheckBox(m_pDisplaySettingPanel, SampleHive::ID::SD_ShowSplash, "Show splash on startup",
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_pShowSplashCheck->SetValue(serializer.DeserializeShowSplash());
|
||||
|
||||
m_pCollectionSettingPanel = new wxPanel(m_pNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
m_pCollectionMainSizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_pCollectionImportDirSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_pCollectionImportOptionsSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_pCollectionShowExtensionSizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_pDoubleClickToPlaySizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
wxString defaultDir = wxGetHomeDir();
|
||||
|
||||
m_pAutoImportCheck = new wxCheckBox(m_pCollectionSettingPanel, SampleHive::ID::SD_AutoImport, "Auto import",
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_pImportDirLocation = new wxTextCtrl(m_pCollectionSettingPanel, wxID_ANY, defaultDir,
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_pImportDirLocation->Disable();
|
||||
m_pBrowseAutoImportDirButton = new wxButton(m_pCollectionSettingPanel, SampleHive::ID::SD_BrowseAutoImportDir, "Browse",
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_pBrowseAutoImportDirButton->Disable();
|
||||
m_pFollowSymLinksCheck = new wxCheckBox(m_pCollectionSettingPanel, SampleHive::ID::SD_FollowSymLinks,
|
||||
"Follow symbolic links", wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_pFollowSymLinksCheck->SetToolTip("Wheather to follow symbolic links");
|
||||
m_pFollowSymLinksCheck->Disable();
|
||||
m_pRecursiveImportCheck = new wxCheckBox(m_pCollectionSettingPanel, SampleHive::ID::SD_RecursiveImport,
|
||||
"Recursive search", wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_pRecursiveImportCheck->SetToolTip("Recursively search for samples in the directory");
|
||||
m_pRecursiveImportCheck->Disable();
|
||||
m_pShowFileExtensionCheck = new wxCheckBox(m_pCollectionSettingPanel, SampleHive::ID::SD_ShowFileExtension,
|
||||
"Show file extension", wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_pShowFileExtensionCheck->SetToolTip("Weather to show file extension");
|
||||
m_pDoubleClickToPlayCheck = new wxCheckBox(m_pCollectionSettingPanel, SampleHive::ID::SD_DoubleClickToPlay,
|
||||
"Enable double click to play sample", wxDefaultPosition, wxDefaultSize, 0);
|
||||
|
||||
m_pConfigurationSettingPanel = new wxPanel(m_pNotebook, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
m_pGeneralMainSizer = new wxFlexGridSizer(2, 3, 0, 0);
|
||||
m_pGeneralMainSizer->AddGrowableCol(1);
|
||||
m_pGeneralMainSizer->SetFlexibleDirection(wxBOTH);
|
||||
m_pGeneralMainSizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
|
||||
|
||||
m_pConfigLabel = new wxStaticText(m_pConfigurationSettingPanel, wxID_ANY,
|
||||
"Default configuration file location", wxDefaultPosition, wxDefaultSize);
|
||||
m_pConfigText = new wxTextCtrl(m_pConfigurationSettingPanel, wxID_ANY, static_cast<std::string>(CONFIG_FILEPATH),
|
||||
wxDefaultPosition, wxDefaultSize);
|
||||
m_pConfigBrowse = new wxButton(m_pConfigurationSettingPanel, SampleHive::ID::SD_BrowseConfigDir, "Browse",
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_pDatabaseLabel = new wxStaticText(m_pConfigurationSettingPanel, wxID_ANY, "Default database location",
|
||||
wxDefaultPosition, wxDefaultSize);
|
||||
m_pDatabaseText = new wxTextCtrl(m_pConfigurationSettingPanel, wxID_ANY, static_cast<std::string>(DATABASE_FILEPATH),
|
||||
wxDefaultPosition, wxDefaultSize);
|
||||
m_pDatabaseBrowse = new wxButton(m_pConfigurationSettingPanel, SampleHive::ID::SD_BrowseDatabaseDir, "Browse",
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
|
||||
m_pNotebook->AddPage(m_pDisplaySettingPanel, "Display");
|
||||
m_pNotebook->AddPage(m_pCollectionSettingPanel, "Collection");
|
||||
m_pNotebook->AddPage(m_pConfigurationSettingPanel, "General");
|
||||
|
||||
m_pOkButton = new wxButton(m_pPanel, wxID_OK, "OK", wxDefaultPosition, wxDefaultSize);
|
||||
m_pCancelButton = new wxButton(m_pPanel, wxID_CANCEL, "Cancel", wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
LoadDefaultConfig();
|
||||
|
||||
// Bind events
|
||||
Bind(wxEVT_CHECKBOX, &cSettings::OnCheckAutoImport, this, SampleHive::ID::SD_AutoImport);
|
||||
Bind(wxEVT_CHECKBOX, &cSettings::OnCheckFollowSymLinks, this, SampleHive::ID::SD_FollowSymLinks);
|
||||
Bind(wxEVT_CHECKBOX, &cSettings::OnCheckRecursiveImport, this, SampleHive::ID::SD_RecursiveImport);
|
||||
Bind(wxEVT_CHECKBOX, &cSettings::OnCheckShowFileExtension, this, SampleHive::ID::SD_ShowFileExtension);
|
||||
Bind(wxEVT_CHECKBOX, &cSettings::OnCheckEnableDoubleClickToPlay, this, SampleHive::ID::SD_DoubleClickToPlay);
|
||||
Bind(wxEVT_SPINCTRL, &cSettings::OnChangeFontSize, this, SampleHive::ID::SD_FontSize);
|
||||
Bind(wxEVT_BUTTON, &cSettings::OnSelectFont, this, SampleHive::ID::SD_FontBrowseButton);
|
||||
Bind(wxEVT_BUTTON, &cSettings::OnClickBrowseAutoImportDir, this, SampleHive::ID::SD_BrowseAutoImportDir);
|
||||
Bind(wxEVT_BUTTON, &cSettings::OnClickConfigBrowse, this, SampleHive::ID::SD_BrowseConfigDir);
|
||||
Bind(wxEVT_BUTTON, &cSettings::OnClickDatabaseBrowse, this, SampleHive::ID::SD_BrowseDatabaseDir);
|
||||
Bind(wxEVT_COLOURPICKER_CHANGED, &cSettings::OnChangeWaveformColour, this, SampleHive::ID::SD_WaveformColourPickerCtrl);
|
||||
Bind(wxEVT_CHECKBOX, &cSettings::OnCheckShowSplash, this, SampleHive::ID::SD_ShowSplash);
|
||||
|
||||
// Adding controls to sizers
|
||||
m_pNotebookSizer->Add(m_pNotebook, 1, wxALL | wxEXPAND, 2);
|
||||
|
||||
m_pGeneralMainSizer->Add(m_pConfigLabel, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_pGeneralMainSizer->Add(m_pConfigText, 1, wxALL | wxALIGN_CENTER_VERTICAL | wxEXPAND, 2);
|
||||
m_pGeneralMainSizer->Add(m_pConfigBrowse, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
|
||||
m_pGeneralMainSizer->Add(m_pDatabaseLabel, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_pGeneralMainSizer->Add(m_pDatabaseText, 1, wxALL | wxALIGN_CENTER_VERTICAL | wxEXPAND, 2);
|
||||
m_pGeneralMainSizer->Add(m_pDatabaseBrowse, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
|
||||
m_pDisplayFontSizer->Add(m_pFontTypeText, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_pDisplayFontSizer->Add(m_pFontType, 1, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_pDisplayFontSizer->Add(m_pFontSize, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_pDisplayFontSizer->Add(m_pFontBrowseButton, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_pWaveformColourSizer->Add(m_pWaveformColourLabel, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_pWaveformColourSizer->Add(m_pWaveformColourPickerCtrl, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
|
||||
m_pDisplayTopSizer->Add(m_pDisplayFontSizer, 0, wxALL | wxEXPAND, 2);
|
||||
m_pDisplayTopSizer->Add(m_pWaveformColourSizer, 0, wxALL | wxEXPAND, 2);
|
||||
m_pDisplayTopSizer->Add(m_pShowSplashCheck, 0, wxALL | wxEXPAND, 2);
|
||||
|
||||
m_pCollectionImportDirSizer->Add(m_pAutoImportCheck, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_pCollectionImportDirSizer->Add(m_pImportDirLocation, 1, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_pCollectionImportDirSizer->Add(m_pBrowseAutoImportDirButton, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
|
||||
m_pCollectionImportOptionsSizer->Add(m_pFollowSymLinksCheck, 0, wxALL, 2);
|
||||
m_pCollectionImportOptionsSizer->Add(m_pRecursiveImportCheck, 0, wxALL, 2);
|
||||
m_pCollectionShowExtensionSizer->Add(m_pShowFileExtensionCheck, 0, wxALL, 2);
|
||||
m_pDoubleClickToPlaySizer->Add(m_pDoubleClickToPlayCheck, 0, wxALL, 2);
|
||||
|
||||
m_pCollectionMainSizer->Add(m_pCollectionImportDirSizer, 0, wxALL | wxEXPAND, 2);
|
||||
m_pCollectionMainSizer->Add(m_pCollectionImportOptionsSizer, 0, wxALL | wxEXPAND, 2);
|
||||
m_pCollectionMainSizer->Add(m_pCollectionShowExtensionSizer, 0, wxALL | wxEXPAND, 2);
|
||||
m_pCollectionMainSizer->Add(m_pDoubleClickToPlaySizer, 0, wxALL | wxEXPAND, 2);
|
||||
|
||||
m_pButtonSizer->Add(m_pOkButton, 0, wxALL | wxALIGN_BOTTOM, 2);
|
||||
m_pButtonSizer->Add(m_pCancelButton, 0, wxALL | wxALIGN_BOTTOM, 2);
|
||||
|
||||
m_pMainSizer->Add(m_pNotebookSizer, 1, wxALL | wxEXPAND, 2);
|
||||
m_pMainSizer->Add(m_pButtonSizer, 0, wxALL | wxALIGN_RIGHT, 2);
|
||||
|
||||
// Top panel layout
|
||||
m_pPanel->SetSizer(m_pMainSizer);
|
||||
m_pMainSizer->Fit(m_pPanel);
|
||||
m_pMainSizer->SetSizeHints(m_pPanel);
|
||||
m_pMainSizer->Layout();
|
||||
|
||||
// Display panel layout
|
||||
m_pDisplaySettingPanel->SetSizer(m_pDisplayTopSizer);
|
||||
m_pDisplayTopSizer->Fit(m_pDisplaySettingPanel);
|
||||
m_pDisplayTopSizer->SetSizeHints(m_pDisplaySettingPanel);
|
||||
m_pDisplayTopSizer->Layout();
|
||||
|
||||
// Collection panel layout
|
||||
m_pCollectionSettingPanel->SetSizer(m_pCollectionMainSizer);
|
||||
m_pCollectionMainSizer->Fit(m_pCollectionSettingPanel);
|
||||
m_pCollectionMainSizer->SetSizeHints(m_pCollectionSettingPanel);
|
||||
m_pCollectionMainSizer->Layout();
|
||||
|
||||
// Configuration panel layout
|
||||
m_pConfigurationSettingPanel->SetSizer(m_pGeneralMainSizer);
|
||||
m_pGeneralMainSizer->Fit(m_pConfigurationSettingPanel);
|
||||
m_pGeneralMainSizer->SetSizeHints(m_pConfigurationSettingPanel);
|
||||
m_pGeneralMainSizer->Layout();
|
||||
}
|
||||
|
||||
void cSettings::OnClickConfigBrowse(wxCommandEvent& event)
|
||||
{
|
||||
wxString initial_dir = wxGetHomeDir();
|
||||
|
||||
wxDirDialog dir_dialog(this, "Select a directory..", initial_dir,
|
||||
wxDD_DEFAULT_STYLE |
|
||||
wxDD_DIR_MUST_EXIST |
|
||||
wxDD_NEW_DIR_BUTTON,
|
||||
wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
switch (dir_dialog.ShowModal())
|
||||
{
|
||||
case wxID_OK:
|
||||
{
|
||||
wxString path = dir_dialog.GetPath();
|
||||
m_pConfigText->SetValue(path + "/config.yaml");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void cSettings::OnClickDatabaseBrowse(wxCommandEvent& event)
|
||||
{
|
||||
wxString initial_dir = wxGetHomeDir();
|
||||
|
||||
wxDirDialog dir_dialog(this, "Select a directory..", initial_dir,
|
||||
wxDD_DEFAULT_STYLE |
|
||||
wxDD_DIR_MUST_EXIST |
|
||||
wxDD_NEW_DIR_BUTTON,
|
||||
wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
switch (dir_dialog.ShowModal())
|
||||
{
|
||||
case wxID_OK:
|
||||
{
|
||||
wxString path = dir_dialog.GetPath();
|
||||
m_pDatabaseText->SetValue(path + "/config.yaml");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void cSettings::OnCheckAutoImport(wxCommandEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
if (!m_pAutoImportCheck->GetValue())
|
||||
{
|
||||
m_bAutoImport = false;
|
||||
m_pImportDirLocation->Disable();
|
||||
m_pBrowseAutoImportDirButton->Disable();
|
||||
m_pFollowSymLinksCheck->Disable();
|
||||
m_pRecursiveImportCheck->Disable();
|
||||
|
||||
serializer.SerializeAutoImport(m_bAutoImport, m_pImportDirLocation->GetValue().ToStdString());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bAutoImport = true;
|
||||
m_pImportDirLocation->Enable();
|
||||
m_pBrowseAutoImportDirButton->Enable();
|
||||
m_pFollowSymLinksCheck->Enable();
|
||||
m_pRecursiveImportCheck->Enable();
|
||||
|
||||
serializer.SerializeAutoImport(m_bAutoImport, m_pImportDirLocation->GetValue().ToStdString());
|
||||
}
|
||||
}
|
||||
|
||||
void cSettings::OnCheckFollowSymLinks(wxCommandEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
serializer.SerializeFollowSymLink(m_pFollowSymLinksCheck->GetValue());
|
||||
}
|
||||
|
||||
void cSettings::OnCheckRecursiveImport(wxCommandEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
serializer.SerializeRecursiveImport(m_pRecursiveImportCheck->GetValue());
|
||||
}
|
||||
|
||||
void cSettings::OnCheckShowFileExtension(wxCommandEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
serializer.SerializeShowFileExtension(m_pShowFileExtensionCheck->GetValue());
|
||||
}
|
||||
|
||||
void cSettings::OnCheckEnableDoubleClickToPlay(wxCommandEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
serializer.SerializeDoubleClickToPlay(m_pDoubleClickToPlayCheck->GetValue());
|
||||
}
|
||||
|
||||
void cSettings::OnClickBrowseAutoImportDir(wxCommandEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
wxString initial_dir = wxGetHomeDir();
|
||||
|
||||
wxDirDialog dir_dialog(this, "Select a directory..", initial_dir,
|
||||
wxDD_DEFAULT_STYLE |
|
||||
wxDD_DIR_MUST_EXIST |
|
||||
wxDD_NEW_DIR_BUTTON,
|
||||
wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
switch (dir_dialog.ShowModal())
|
||||
{
|
||||
case wxID_OK:
|
||||
{
|
||||
wxString path = dir_dialog.GetPath();
|
||||
m_pImportDirLocation->SetValue(path);
|
||||
|
||||
serializer.SerializeAutoImport(m_bAutoImport, m_pImportDirLocation->GetValue().ToStdString());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void cSettings::OnSelectFont(wxCommandEvent& event)
|
||||
{
|
||||
wxFontDialog font_dialog(this);
|
||||
|
||||
switch (font_dialog.ShowModal())
|
||||
{
|
||||
case wxID_OK:
|
||||
{
|
||||
wxFontData fontData = font_dialog.GetFontData();
|
||||
m_Font = fontData.GetChosenFont();
|
||||
|
||||
if (m_pFontType->GetCount() > 1)
|
||||
{
|
||||
m_pFontType->Delete(1);
|
||||
m_pFontType->AppendString(m_Font.GetFaceName());
|
||||
m_pFontType->SetSelection(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pFontType->AppendString(m_Font.GetFaceName());
|
||||
m_pFontType->SetSelection(1);
|
||||
}
|
||||
|
||||
SetCustomFont();
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
PrintFont();
|
||||
}
|
||||
|
||||
void cSettings::OnChangeFontSize(wxSpinEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
int font_size = m_pFontSize->GetValue();
|
||||
|
||||
if (m_pFontType->GetStringSelection() == "System default")
|
||||
m_Font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
||||
|
||||
m_Font.SetPointSize(font_size);
|
||||
|
||||
serializer.SerializeFontSettings(m_Font);
|
||||
|
||||
m_pWindow->SetFont(m_Font);
|
||||
this->SetFont(m_Font);
|
||||
|
||||
SH_LOG_DEBUG("Font size: {}", font_size);
|
||||
SH_LOG_DEBUG("Font size: {}", m_Font.GetPointSize());
|
||||
}
|
||||
|
||||
void cSettings::LoadDefaultConfig()
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
wxFont sys_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
||||
wxString system_font = sys_font.GetFaceName();
|
||||
int system_font_size = sys_font.GetPointSize();
|
||||
|
||||
wxString font_face = serializer.DeserializeFontSettings().GetFaceName();
|
||||
int font_size = serializer.DeserializeFontSettings().GetPointSize();
|
||||
|
||||
if (system_font != font_face)
|
||||
{
|
||||
if (m_pFontType->GetCount() > 1)
|
||||
{
|
||||
m_pFontType->Delete(1);
|
||||
m_pFontType->AppendString(font_face);
|
||||
m_pFontType->SetSelection(1);
|
||||
|
||||
m_Font.SetFaceName(font_face);
|
||||
m_Font.SetPointSize(font_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pFontType->AppendString(font_face);
|
||||
m_pFontType->SetSelection(1);
|
||||
|
||||
m_Font.SetFaceName(font_face);
|
||||
m_Font.SetPointSize(font_size);
|
||||
}
|
||||
}
|
||||
|
||||
m_pFontSize->SetValue(font_size);
|
||||
SetCustomFont();
|
||||
|
||||
m_bAutoImport = serializer.DeserializeAutoImport().first;
|
||||
|
||||
m_pAutoImportCheck->SetValue(m_bAutoImport);
|
||||
m_pImportDirLocation->SetValue(serializer.DeserializeAutoImport().second);
|
||||
m_pShowFileExtensionCheck->SetValue(serializer.DeserializeShowFileExtension());
|
||||
m_pDoubleClickToPlayCheck->SetValue(serializer.DeserializeDoubleClickToPlay());
|
||||
m_pFollowSymLinksCheck->SetValue(serializer.DeserializeFollowSymLink());
|
||||
m_pRecursiveImportCheck->SetValue(serializer.DeserializeRecursiveImport());
|
||||
|
||||
if (m_bAutoImport)
|
||||
{
|
||||
m_pImportDirLocation->Enable();
|
||||
m_pBrowseAutoImportDirButton->Enable();
|
||||
m_pFollowSymLinksCheck->Enable();
|
||||
m_pRecursiveImportCheck->Enable();
|
||||
}
|
||||
}
|
||||
|
||||
void cSettings::SetShowExtension(bool value)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
m_pShowFileExtensionCheck->SetValue(value);
|
||||
serializer.SerializeShowFileExtension(value);
|
||||
}
|
||||
|
||||
void cSettings::PrintFont()
|
||||
{
|
||||
SH_LOG_DEBUG("Font face: {}", m_Font.GetFaceName().ToStdString());
|
||||
SH_LOG_DEBUG("Font size: {}", m_Font.GetPointSize());
|
||||
SH_LOG_DEBUG("Font family: {}", m_Font.GetFamilyString().ToStdString());
|
||||
SH_LOG_DEBUG("Font style: {}", m_Font.GetStyleString().ToStdString());
|
||||
SH_LOG_DEBUG("Font weight: {}", m_Font.GetWeightString().ToStdString());
|
||||
}
|
||||
|
||||
void cSettings::SetCustomFont()
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
wxFont sys_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
||||
std::string system_font = sys_font.GetFaceName().ToStdString();
|
||||
int system_font_size = sys_font.GetPointSize();
|
||||
|
||||
wxString font_face = serializer.DeserializeFontSettings().GetFaceName();
|
||||
int font_size = serializer.DeserializeFontSettings().GetPointSize();
|
||||
|
||||
if (m_pFontType->GetStringSelection() == "System default")
|
||||
{
|
||||
m_pWindow->SetFont(sys_font);
|
||||
this->SetFont(sys_font);
|
||||
|
||||
serializer.SerializeFontSettings(sys_font);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pWindow->SetFont(m_Font);
|
||||
this->SetFont(m_Font);
|
||||
|
||||
serializer.SerializeFontSettings(m_Font);
|
||||
}
|
||||
}
|
||||
|
||||
wxString cSettings::GetImportDirPath()
|
||||
{
|
||||
wxString dir = wxEmptyString;
|
||||
|
||||
if (m_pAutoImportCheck->GetValue())
|
||||
dir = m_pImportDirLocation->GetValue();
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
void cSettings::OnChangeWaveformColour(wxColourPickerEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
wxColour colour = m_pWaveformColourPickerCtrl->GetColour();
|
||||
|
||||
wxColour wave_colour = serializer.DeserializeWaveformColour();
|
||||
|
||||
if (colour != wave_colour)
|
||||
{
|
||||
SH_LOG_INFO("Waveform colour changed.");
|
||||
m_bWaveformColourChanged = true;
|
||||
|
||||
serializer.SerializeWaveformColour(colour);
|
||||
}
|
||||
else
|
||||
{
|
||||
SH_LOG_INFO("Waveform colour not changed.");
|
||||
m_bWaveformColourChanged = false;
|
||||
|
||||
serializer.SerializeWaveformColour(colour);
|
||||
}
|
||||
}
|
||||
|
||||
void cSettings::OnCheckShowSplash(wxCommandEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
serializer.SerializeShowSplash(m_pShowSplashCheck->GetValue());
|
||||
}
|
||||
|
||||
cSettings::~cSettings()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -23,6 +23,7 @@
|
|||
#include <string>
|
||||
|
||||
#include <wx/button.h>
|
||||
#include <wx/clrpicker.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/choice.h>
|
||||
#include <wx/dialog.h>
|
||||
|
|
@ -39,98 +40,26 @@
|
|||
#include <wx/toplevel.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
class Settings : public wxDialog
|
||||
class cSettings : public wxDialog
|
||||
{
|
||||
public:
|
||||
Settings(const std::string& configFilepath, const std::string& databaseFilepath);
|
||||
Settings(wxWindow* window, const std::string& configFilepath, const std::string& databaseFilepath);
|
||||
|
||||
~Settings();
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
wxWindow* m_Window;
|
||||
|
||||
const std::string& m_ConfigFilepath;
|
||||
const 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;
|
||||
wxBoxSizer* m_ShowFileExtensionSizer;
|
||||
wxCheckBox* m_AutoImportCheck;
|
||||
wxCheckBox* m_ShowFileExtensionCheck;
|
||||
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;
|
||||
bool bShowExtension = true;
|
||||
cSettings(wxWindow* window);
|
||||
~cSettings();
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
void OnClickConfigBrowse(wxCommandEvent& event);
|
||||
void OnClickDatabaseBrowse(wxCommandEvent& event);
|
||||
void OnCheckAutoImport(wxCommandEvent& event);
|
||||
void OnCheckFollowSymLinks(wxCommandEvent& event);
|
||||
void OnCheckRecursiveImport(wxCommandEvent& event);
|
||||
void OnCheckShowFileExtension(wxCommandEvent& event);
|
||||
void OnCheckEnableDoubleClickToPlay(wxCommandEvent& event);
|
||||
void OnClickBrowseAutoImportDir(wxCommandEvent& event);
|
||||
void OnChangeFontSize(wxSpinEvent& event);
|
||||
void OnSelectFont(wxCommandEvent& event);
|
||||
void OnChangeWaveformColour(wxColourPickerEvent& event);
|
||||
void OnCheckShowSplash(wxCommandEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void SetCustomFont();
|
||||
|
|
@ -144,7 +73,92 @@ class Settings : public wxDialog
|
|||
// Getters
|
||||
wxString GetImportDirPath();
|
||||
|
||||
inline wxFont GetFontType() { return m_Font; };
|
||||
inline bool CanAutoImport() { return bAutoImport; };
|
||||
inline bool ShouldShowFileExtension() { return bShowExtension; };
|
||||
// inline wxFont GetFontType() { return m_Font; };
|
||||
inline bool CanAutoImport() { return m_bAutoImport; };
|
||||
inline bool IsWaveformColourChanged() { return m_bWaveformColourChanged; }
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Setters
|
||||
void SetShowExtension(bool value);
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
wxWindow* m_pWindow = nullptr;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
// Top panel for wxDialog
|
||||
wxPanel* m_pPanel = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Notebook page panels
|
||||
wxPanel* m_pDisplaySettingPanel = nullptr;
|
||||
wxPanel* m_pCollectionSettingPanel = nullptr;
|
||||
wxPanel* m_pConfigurationSettingPanel = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Top panel sizers
|
||||
wxBoxSizer* m_pMainSizer = nullptr;
|
||||
wxBoxSizer* m_pNotebookSizer = nullptr;
|
||||
wxBoxSizer* m_pButtonSizer = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Notebook
|
||||
wxNotebook* m_pNotebook = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Display page
|
||||
wxBoxSizer* m_pDisplayTopSizer = nullptr;
|
||||
wxBoxSizer* m_pDisplayFontSizer = nullptr;
|
||||
wxStaticText* m_pRowHeightText = nullptr;
|
||||
wxStaticText* m_pFontTypeText = nullptr;
|
||||
wxChoice* m_pRowHeight = nullptr;
|
||||
wxChoice* m_pFontType = nullptr;
|
||||
wxButton* m_pFontBrowseButton = nullptr;
|
||||
wxSpinCtrl* m_pFontSize = nullptr;
|
||||
wxBoxSizer* m_pWaveformColourSizer = nullptr;
|
||||
wxStaticText* m_pWaveformColourLabel = nullptr;
|
||||
wxColourPickerCtrl* m_pWaveformColourPickerCtrl = nullptr;
|
||||
wxCheckBox* m_pShowSplashCheck = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Collection page
|
||||
wxBoxSizer* m_pCollectionMainSizer = nullptr;
|
||||
wxBoxSizer* m_pCollectionImportDirSizer = nullptr;
|
||||
wxBoxSizer* m_pCollectionImportOptionsSizer = nullptr;
|
||||
wxBoxSizer* m_pCollectionShowExtensionSizer = nullptr;
|
||||
wxBoxSizer* m_pDoubleClickToPlaySizer = nullptr;
|
||||
wxCheckBox* m_pAutoImportCheck = nullptr;
|
||||
wxCheckBox* m_pFollowSymLinksCheck = nullptr;
|
||||
wxCheckBox* m_pRecursiveImportCheck = nullptr;
|
||||
wxCheckBox* m_pShowFileExtensionCheck = nullptr;
|
||||
wxCheckBox* m_pDoubleClickToPlayCheck = nullptr;
|
||||
wxTextCtrl* m_pImportDirLocation = nullptr;
|
||||
wxButton* m_pBrowseAutoImportDirButton = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// General configuration page
|
||||
wxFlexGridSizer* m_pGeneralMainSizer = nullptr;
|
||||
wxStaticText* m_pConfigLabel = nullptr;
|
||||
wxStaticText* m_pDatabaseLabel = nullptr;
|
||||
wxTextCtrl* m_pConfigText = nullptr;
|
||||
wxTextCtrl* m_pDatabaseText = nullptr;
|
||||
wxButton* m_pConfigBrowse = nullptr;
|
||||
wxButton* m_pDatabaseBrowse = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Common buttons for wxDialog
|
||||
wxButton* m_pOkButton = nullptr;
|
||||
wxButton* m_pCancelButton = nullptr;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
wxFont m_Font;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
bool m_bAutoImport = false;
|
||||
// bool bFollowSymLinks = false;
|
||||
// bool bShowExtension = true;
|
||||
bool m_bWaveformColourChanged = false;
|
||||
};
|
||||
|
|
@ -0,0 +1,334 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "GUI/Dialogs/TagEditor.hpp"
|
||||
#include "Database/Database.hpp"
|
||||
#include "Utility/ControlIDs.hpp"
|
||||
#include "Utility/Log.hpp"
|
||||
#include "Utility/Paths.hpp"
|
||||
#include "Utility/Event.hpp"
|
||||
#include "Utility/Signal.hpp"
|
||||
|
||||
#include <wx/defs.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/msgdlg.h>
|
||||
#include <wx/stringimpl.h>
|
||||
#include <wx/textdlg.h>
|
||||
|
||||
cTagEditor::cTagEditor(wxWindow* window, const std::string& filename)
|
||||
: wxDialog(window, wxID_ANY, "Edit tags", wxDefaultPosition,
|
||||
wxSize(640, 360), wxDEFAULT_DIALOG_STYLE | wxSTAY_ON_TOP),
|
||||
m_pWindow(window), m_Filename(filename), tags(filename)
|
||||
{
|
||||
m_pPanel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
m_pMainSizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_pButtonSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_pEditTagSizer = new wxFlexGridSizer(6, 2, 0, 0);
|
||||
m_pEditTagSizer->AddGrowableCol(1);
|
||||
m_pEditTagSizer->SetFlexibleDirection(wxBOTH);
|
||||
m_pEditTagSizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
|
||||
m_pSampleTypeSizer = new wxFlexGridSizer(1, 3, 0, 0);
|
||||
m_pSampleTypeSizer->AddGrowableCol(1);
|
||||
m_pSampleTypeSizer->SetFlexibleDirection(wxBOTH);
|
||||
m_pSampleTypeSizer->SetNonFlexibleGrowMode(wxFLEX_GROWMODE_SPECIFIED);
|
||||
m_pStaticEditTagSizer = new wxStaticBoxSizer(wxVERTICAL, m_pPanel, "Edit tags");
|
||||
m_pStaticSampleTypeSizer = new wxStaticBoxSizer(wxVERTICAL, m_pPanel, "Sample type");
|
||||
|
||||
wxString choices[] = {"Kick", "Snare", "Clap", "HiHat", "Cymbal", "Cowbell", "Ride", "Tom", "Shaker", "Percussion"};
|
||||
|
||||
m_pTitleCheck = new wxCheckBox(m_pPanel, SampleHive::ID::ET_TitleCheck, "Title", wxDefaultPosition, wxDefaultSize);
|
||||
m_pArtistCheck = new wxCheckBox(m_pPanel, SampleHive::ID::ET_ArtistCheck, "Artist", wxDefaultPosition, wxDefaultSize);
|
||||
m_pAlbumCheck = new wxCheckBox(m_pPanel, SampleHive::ID::ET_AlbumCheck, "Album", wxDefaultPosition, wxDefaultSize);
|
||||
m_pGenreCheck = new wxCheckBox(m_pPanel, SampleHive::ID::ET_GenreCheck, "Genre", wxDefaultPosition, wxDefaultSize);
|
||||
m_pCommentCheck = new wxCheckBox(m_pPanel, SampleHive::ID::ET_CommentsCheck, "Comments", wxDefaultPosition, wxDefaultSize);
|
||||
m_pSampleTypeCheck = new wxCheckBox(m_pPanel, SampleHive::ID::ET_TypeCheck, "Type", wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
m_pTitleText = new wxTextCtrl(m_pPanel, wxID_ANY, tags.GetAudioInfo().title, wxDefaultPosition, wxDefaultSize);
|
||||
m_pTitleText->Disable();
|
||||
m_pArtistText = new wxTextCtrl(m_pPanel, wxID_ANY, tags.GetAudioInfo().artist, wxDefaultPosition, wxDefaultSize);
|
||||
m_pArtistText->Disable();
|
||||
m_pAlbumText = new wxTextCtrl(m_pPanel, wxID_ANY, tags.GetAudioInfo().album, wxDefaultPosition, wxDefaultSize);
|
||||
m_pAlbumText->Disable();
|
||||
m_pGenreText = new wxTextCtrl(m_pPanel, wxID_ANY, tags.GetAudioInfo().genre, wxDefaultPosition, wxDefaultSize);
|
||||
m_pGenreText->Disable();
|
||||
m_pCommentText = new wxTextCtrl(m_pPanel, wxID_ANY, tags.GetAudioInfo().comment, wxDefaultPosition, wxDefaultSize);
|
||||
m_pCommentText->Disable();
|
||||
m_pSampleTypeChoice = new wxChoice(m_pPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 10, choices, wxCB_SORT);
|
||||
m_pSampleTypeChoice->Disable();
|
||||
|
||||
m_pSampleTypeButton = new wxButton(m_pPanel, SampleHive::ID::ET_CustomTag, "Custom", wxDefaultPosition, wxDefaultSize);
|
||||
m_pSampleTypeButton->Disable();
|
||||
|
||||
m_pOkButton = new wxButton(m_pPanel, wxID_OK, "OK", wxDefaultPosition, wxDefaultSize);
|
||||
m_pApplyButton = new wxButton(m_pPanel, wxID_APPLY, "Apply", wxDefaultPosition, wxDefaultSize);
|
||||
m_pCancelButton = new wxButton(m_pPanel, wxID_CANCEL, "Cancel", wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
// Binding events
|
||||
Bind(wxEVT_CHECKBOX, &cTagEditor::OnCheckTitle, this, SampleHive::ID::ET_TitleCheck);
|
||||
Bind(wxEVT_CHECKBOX, &cTagEditor::OnCheckArtist, this, SampleHive::ID::ET_ArtistCheck);
|
||||
Bind(wxEVT_CHECKBOX, &cTagEditor::OnCheckAlbum, this, SampleHive::ID::ET_AlbumCheck);
|
||||
Bind(wxEVT_CHECKBOX, &cTagEditor::OnCheckGenre, this, SampleHive::ID::ET_GenreCheck);
|
||||
Bind(wxEVT_CHECKBOX, &cTagEditor::OnCheckComments, this, SampleHive::ID::ET_CommentsCheck);
|
||||
Bind(wxEVT_CHECKBOX, &cTagEditor::OnCheckType, this, SampleHive::ID::ET_TypeCheck);
|
||||
|
||||
Bind(wxEVT_BUTTON, &cTagEditor::OnClickCustomTagButton, this, SampleHive::ID::ET_CustomTag);
|
||||
|
||||
Bind(wxEVT_BUTTON, &cTagEditor::OnClickApply, this, wxID_APPLY);
|
||||
|
||||
m_pEditTagSizer->Add(m_pTitleCheck, 0, wxALL | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_pEditTagSizer->Add(m_pTitleText, 1, wxALL | wxALIGN_CENTER_VERTICAL | wxEXPAND, 2);
|
||||
|
||||
m_pEditTagSizer->Add(m_pArtistCheck, 0, wxALL | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_pEditTagSizer->Add(m_pArtistText, 1, wxALL | wxALIGN_CENTER_VERTICAL | wxEXPAND, 2);
|
||||
|
||||
m_pEditTagSizer->Add(m_pAlbumCheck, 0, wxALL | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_pEditTagSizer->Add(m_pAlbumText, 1, wxALL | wxALIGN_CENTER_VERTICAL | wxEXPAND, 2);
|
||||
|
||||
m_pEditTagSizer->Add(m_pGenreCheck, 0, wxALL | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_pEditTagSizer->Add(m_pGenreText, 1, wxALL | wxALIGN_CENTER_VERTICAL | wxEXPAND, 2);
|
||||
|
||||
m_pEditTagSizer->Add(m_pCommentCheck, 0, wxALL | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_pEditTagSizer->Add(m_pCommentText, 1, wxALL | wxALIGN_CENTER_VERTICAL | wxEXPAND, 2);
|
||||
|
||||
m_pSampleTypeSizer->Add(m_pSampleTypeCheck, 0, wxALL | wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_pSampleTypeSizer->Add(m_pSampleTypeChoice, 1, wxALL | wxALIGN_CENTER_VERTICAL | wxEXPAND, 2);
|
||||
m_pSampleTypeSizer->Add(m_pSampleTypeButton, 0, wxALL | wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL, 2);
|
||||
|
||||
m_pStaticEditTagSizer->Add(m_pEditTagSizer, 1, wxALL | wxEXPAND, 2);
|
||||
m_pStaticSampleTypeSizer->Add(m_pSampleTypeSizer, 1, wxALL | wxEXPAND, 2);
|
||||
|
||||
m_pButtonSizer->Add(m_pOkButton, 0, wxALL | wxALIGN_BOTTOM, 2);
|
||||
m_pButtonSizer->Add(m_pApplyButton, 0, wxALL | wxALIGN_BOTTOM, 2);
|
||||
m_pButtonSizer->Add(m_pCancelButton, 0, wxALL | wxALIGN_BOTTOM, 2);
|
||||
|
||||
m_pMainSizer->Add(m_pStaticEditTagSizer, 1, wxALL | wxEXPAND, 2);
|
||||
m_pMainSizer->Add(m_pStaticSampleTypeSizer, 1, wxALL | wxEXPAND, 2);
|
||||
m_pMainSizer->Add(m_pButtonSizer, 0, wxALL | wxALIGN_RIGHT, 2);
|
||||
|
||||
// Top panel layout
|
||||
m_pPanel->SetSizer(m_pMainSizer);
|
||||
m_pMainSizer->Fit(m_pPanel);
|
||||
m_pMainSizer->SetSizeHints(m_pPanel);
|
||||
m_pMainSizer->Layout();
|
||||
}
|
||||
|
||||
void cTagEditor::OnCheckTitle(wxCommandEvent &event)
|
||||
{
|
||||
if (m_pTitleCheck->GetValue())
|
||||
{
|
||||
m_pTitleText->Enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pTitleText->Disable();
|
||||
}
|
||||
}
|
||||
|
||||
void cTagEditor::OnCheckArtist(wxCommandEvent &event)
|
||||
{
|
||||
if (m_pArtistCheck->GetValue())
|
||||
{
|
||||
m_pArtistText->Enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pArtistText->Disable();
|
||||
}
|
||||
}
|
||||
|
||||
void cTagEditor::OnCheckAlbum(wxCommandEvent &event)
|
||||
{
|
||||
if (m_pAlbumCheck->GetValue())
|
||||
{
|
||||
m_pAlbumText->Enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pAlbumText->Disable();
|
||||
}
|
||||
}
|
||||
|
||||
void cTagEditor::OnCheckGenre(wxCommandEvent &event)
|
||||
{
|
||||
if (m_pGenreCheck->GetValue())
|
||||
{
|
||||
m_pGenreText->Enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pGenreText->Disable();
|
||||
}
|
||||
}
|
||||
|
||||
void cTagEditor::OnCheckComments(wxCommandEvent &event)
|
||||
{
|
||||
if (m_pCommentCheck->GetValue())
|
||||
{
|
||||
m_pCommentText->Enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pCommentText->Disable();
|
||||
}
|
||||
}
|
||||
|
||||
void cTagEditor::OnCheckType(wxCommandEvent &event)
|
||||
{
|
||||
if (m_pSampleTypeCheck->GetValue())
|
||||
{
|
||||
m_pSampleTypeChoice->Enable();
|
||||
m_pSampleTypeButton->Enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pSampleTypeChoice->Disable();
|
||||
m_pSampleTypeButton->Disable();
|
||||
}
|
||||
}
|
||||
|
||||
void cTagEditor::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_pSampleTypeChoice->AppendString(tag);
|
||||
m_pSampleTypeChoice->SetStringSelection(tag);
|
||||
break;
|
||||
}
|
||||
case wxID_CANCEL:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void cTagEditor::OnClickApply(wxCommandEvent& event)
|
||||
{
|
||||
cDatabase db;
|
||||
|
||||
wxString title = m_pTitleText->GetValue();
|
||||
wxString artist = m_pArtistText->GetValue();
|
||||
wxString album = m_pAlbumText->GetValue();
|
||||
wxString genre = m_pGenreText->GetValue();
|
||||
wxString comment = m_pCommentText->GetValue();
|
||||
wxString type = m_pSampleTypeChoice->GetStringSelection();
|
||||
|
||||
std::string sampleType = db.GetSampleType(m_Filename);
|
||||
|
||||
std::string filename = wxString(m_Filename).AfterLast('/').BeforeLast('.').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_pTitleCheck->GetValue() && m_pTitleText->GetValue() != tags.GetAudioInfo().title)
|
||||
{
|
||||
SH_LOG_INFO("Changing title tag..");
|
||||
tags.SetTitle(title.ToStdString());
|
||||
|
||||
info_msg = wxString::Format("Successfully changed title tag to %s", title);
|
||||
}
|
||||
|
||||
if (m_pArtistCheck->GetValue() && m_pArtistText->GetValue() != tags.GetAudioInfo().artist)
|
||||
{
|
||||
SH_LOG_INFO("Changing artist tag..");
|
||||
tags.SetArtist(artist.ToStdString());
|
||||
|
||||
db.UpdateSamplePack(m_Filename, artist.ToStdString());
|
||||
|
||||
SH_LOG_DEBUG("SAMPLE FILENAME HERE: %s", m_Filename);
|
||||
|
||||
info_msg = wxString::Format("Successfully changed artist tag to %s", artist);
|
||||
}
|
||||
|
||||
if (m_pAlbumCheck->GetValue() && m_pAlbumText->GetValue() != tags.GetAudioInfo().album)
|
||||
{
|
||||
SH_LOG_INFO("Changing album tag..");
|
||||
tags.SetAlbum(album.ToStdString());
|
||||
|
||||
info_msg = wxString::Format("Successfully changed album tag to %s", album);
|
||||
}
|
||||
|
||||
if (m_pGenreCheck->GetValue() && m_pGenreText->GetValue() != tags.GetAudioInfo().genre)
|
||||
{
|
||||
SH_LOG_INFO("Changing genre tag..");
|
||||
tags.SetGenre(genre.ToStdString());
|
||||
|
||||
info_msg = wxString::Format("Successfully changed genre tag to %s", genre);
|
||||
}
|
||||
|
||||
if (m_pCommentCheck->GetValue() && m_pCommentText->GetValue() != tags.GetAudioInfo().comment)
|
||||
{
|
||||
SH_LOG_INFO("Changing comment tag..");
|
||||
tags.SetComment(comment.ToStdString());
|
||||
|
||||
info_msg = wxString::Format("Successfully changed comment tag to %s", comment);
|
||||
}
|
||||
|
||||
if (m_pSampleTypeCheck->GetValue() && m_pSampleTypeChoice->GetStringSelection() != sampleType)
|
||||
{
|
||||
SH_LOG_INFO("Changing type tag..");
|
||||
db.UpdateSampleType(filename, type.ToStdString());
|
||||
|
||||
info_msg = wxString::Format("Successfully changed type tag to %s", type);
|
||||
}
|
||||
break;
|
||||
case wxID_NO:
|
||||
break;
|
||||
default:
|
||||
info_msg = "Error, cannot change tag!";
|
||||
}
|
||||
|
||||
SampleHive::cSignal::SendInfoBarMessage(info_msg, wxICON_INFORMATION, *this, true);
|
||||
}
|
||||
|
||||
// void cTagEditor::SendInfoBarMessage(const wxString& msg, int mode)
|
||||
// {
|
||||
// SH_LOG_INFO("{} called..", __FUNCTION__);
|
||||
|
||||
// SampleHive::SH_InfoBarMessageEvent event(SampleHive::SH_EVT_INFOBAR_MESSAGE_SHOW, this->GetId());
|
||||
// event.SetEventObject(this);
|
||||
|
||||
// event.SetInfoBarMessage({ msg, mode });
|
||||
|
||||
// GetParent()->GetEventHandler()->ProcessEvent(event);
|
||||
// }
|
||||
|
||||
cTagEditor::~cTagEditor()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "Utility/Tags.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <wx/button.h>
|
||||
|
|
@ -34,61 +36,11 @@
|
|||
#include <wx/toplevel.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
#include "Tags.hpp"
|
||||
|
||||
class TagEditor : public wxDialog
|
||||
class cTagEditor : public wxDialog
|
||||
{
|
||||
public:
|
||||
TagEditor(wxWindow* window, const std::string& dbPath, const std::string& filename, wxInfoBar& info_bar);
|
||||
~TagEditor();
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
wxWindow* m_Window;
|
||||
const std::string m_DatabaseFilepath;
|
||||
const 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;
|
||||
cTagEditor(wxWindow* window, const std::string& filename);
|
||||
~cTagEditor();
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
|
|
@ -105,4 +57,51 @@ class TagEditor : public wxDialog
|
|||
|
||||
// -------------------------------------------------------------------
|
||||
void OnClickApply(wxCommandEvent& event);
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
wxWindow* m_pWindow = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
const std::string& m_Filename;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
// Top panel for wxDialog
|
||||
wxPanel* m_pPanel = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Top panel sizers
|
||||
wxBoxSizer* m_pMainSizer = nullptr;
|
||||
wxFlexGridSizer* m_pEditTagSizer = nullptr;
|
||||
wxFlexGridSizer* m_pSampleTypeSizer = nullptr;
|
||||
wxBoxSizer* m_pButtonSizer = nullptr;
|
||||
wxStaticBoxSizer* m_pStaticEditTagSizer = nullptr;
|
||||
wxStaticBoxSizer* m_pStaticSampleTypeSizer = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Dialog controls
|
||||
wxCheckBox* m_pTitleCheck = nullptr;
|
||||
wxCheckBox* m_pArtistCheck = nullptr;
|
||||
wxCheckBox* m_pAlbumCheck = nullptr;
|
||||
wxCheckBox* m_pGenreCheck = nullptr;
|
||||
wxCheckBox* m_pCommentCheck = nullptr;
|
||||
wxCheckBox* m_pSampleTypeCheck = nullptr;
|
||||
wxTextCtrl* m_pTitleText = nullptr;
|
||||
wxTextCtrl* m_pArtistText = nullptr;
|
||||
wxTextCtrl* m_pAlbumText = nullptr;
|
||||
wxTextCtrl* m_pGenreText = nullptr;
|
||||
wxTextCtrl* m_pCommentText = nullptr;
|
||||
wxChoice* m_pSampleTypeChoice = nullptr;
|
||||
wxButton* m_pSampleTypeButton = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Common buttons for wxDialog
|
||||
wxButton* m_pOkButton = nullptr;
|
||||
wxButton* m_pApplyButton = nullptr;
|
||||
wxButton* m_pCancelButton = nullptr;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
SampleHive::cTags tags;
|
||||
};
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Database/Database.hpp"
|
||||
#include "GUI/DirectoryBrowser.hpp"
|
||||
#include "Utility/ControlIDs.hpp"
|
||||
#include "Utility/HiveData.hpp"
|
||||
#include "Utility/Log.hpp"
|
||||
#include "Utility/Paths.hpp"
|
||||
#include "Utility/Sample.hpp"
|
||||
#include "Utility/Serialize.hpp"
|
||||
#include "Utility/Utils.hpp"
|
||||
|
||||
#include <wx/dataobj.h>
|
||||
#include <wx/dir.h>
|
||||
#include <wx/dnd.h>
|
||||
#include <wx/treebase.h>
|
||||
|
||||
cDirectoryBrowser::cDirectoryBrowser(wxWindow* window)
|
||||
: wxGenericDirCtrl(window, SampleHive::ID::BC_DirCtrl, wxDirDialogDefaultFolderStr, wxDefaultPosition,
|
||||
wxDefaultSize, wxDIRCTRL_SHOW_FILTERS,
|
||||
_("All files|*|Ogg files (*.ogg)|*.ogg|Wav files (*.wav)|*.wav|"
|
||||
"Flac files (*.flac)|*.flac"), 0),
|
||||
m_pWindow(window)
|
||||
{
|
||||
SetPath(USER_HOME_DIR);
|
||||
|
||||
Bind(wxEVT_DIRCTRL_FILEACTIVATED, &cDirectoryBrowser::OnClickDirCtrl, this, SampleHive::ID::BC_DirCtrl);
|
||||
Bind(wxEVT_TREE_BEGIN_DRAG, &cDirectoryBrowser::OnDragFromDirCtrl, this, this->GetTreeCtrl()->GetId());
|
||||
Bind(wxEVT_TREE_ITEM_ACTIVATED, &cDirectoryBrowser::OnDirCtrlExpanded, this, this->GetTreeCtrl()->GetId());
|
||||
}
|
||||
|
||||
void cDirectoryBrowser::OnClickDirCtrl(wxCommandEvent& event)
|
||||
{
|
||||
wxArrayString path;
|
||||
path.push_back(this->GetFilePath());
|
||||
|
||||
SampleHive::cUtils::Get().AddSamples(path, m_pWindow);
|
||||
}
|
||||
|
||||
// Temporary function to check drag and drop result
|
||||
void LogDragResult(wxDragResult result)
|
||||
{
|
||||
wxString msg;
|
||||
switch (result)
|
||||
{
|
||||
case wxDragError: msg = "Error!"; break;
|
||||
case wxDragNone: msg = "Nothing"; break;
|
||||
case wxDragCopy: msg = "Copied"; break;
|
||||
case wxDragMove: msg = "Moved"; break;
|
||||
case wxDragCancel: msg = "Cancelled"; break;
|
||||
default: msg = "Huh?"; break;
|
||||
}
|
||||
|
||||
SH_LOG_DEBUG("Drag result: {}", msg.ToStdString());
|
||||
}
|
||||
|
||||
void cDirectoryBrowser::OnDragFromDirCtrl(wxTreeEvent& event)
|
||||
{
|
||||
wxFileDataObject file_data;
|
||||
file_data.AddFile(this->GetPath(event.GetItem()));
|
||||
|
||||
wxDropSource drop_source(this);
|
||||
drop_source.SetData(file_data);
|
||||
|
||||
LogDragResult(drop_source.DoDragDrop());
|
||||
}
|
||||
|
||||
void cDirectoryBrowser::OnDirCtrlExpanded(wxTreeEvent& event)
|
||||
{
|
||||
cDatabase db;
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
if (serializer.DeserializeDemoMode())
|
||||
{
|
||||
wxBusyCursor busy_cursor;
|
||||
wxWindowDisabler window_disabler;
|
||||
|
||||
wxString filepath;
|
||||
wxArrayString filepath_array;
|
||||
|
||||
const wxString pathToDirectory = this->GetPath(event.GetItem());
|
||||
|
||||
size_t number_of_files = wxDir::GetAllFiles(pathToDirectory, &filepath_array, wxEmptyString, wxDIR_FILES);
|
||||
|
||||
for (size_t i = 0; i < number_of_files; i++)
|
||||
{
|
||||
filepath = filepath_array[i];
|
||||
|
||||
if (wxFileExists(filepath))
|
||||
{
|
||||
filepath_array.push_back(filepath);
|
||||
}
|
||||
else if (wxDirExists(filepath))
|
||||
{
|
||||
wxDir::GetAllFiles(filepath, &filepath_array);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete all Files
|
||||
if (SampleHive::cHiveData::Get().GetListCtrlItemCount() >= 1)
|
||||
{
|
||||
db.DeleteAllSamples();
|
||||
SampleHive::cHiveData::Get().ListCtrlDeleteAllItems();
|
||||
}
|
||||
|
||||
SampleHive::cUtils::Get().AddSamples(filepath_array, this);
|
||||
|
||||
}
|
||||
else
|
||||
event.Veto();
|
||||
}
|
||||
|
||||
cDirectoryBrowser::~cDirectoryBrowser()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wx/control.h>
|
||||
#include <wx/dirctrl.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
class cDirectoryBrowser : public wxGenericDirCtrl
|
||||
{
|
||||
public:
|
||||
cDirectoryBrowser(wxWindow* window);
|
||||
~cDirectoryBrowser();
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
// DirCtrl event handlers
|
||||
void OnClickDirCtrl(wxCommandEvent& event);
|
||||
void OnDragFromDirCtrl(wxTreeEvent& event);
|
||||
void OnDirCtrlExpanded(wxTreeEvent& event);
|
||||
|
||||
private:
|
||||
wxWindow* m_pWindow = nullptr;
|
||||
};
|
||||
|
|
@ -0,0 +1,736 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "GUI/Hives.hpp"
|
||||
#include "Database/Database.hpp"
|
||||
#include "Utility/ControlIDs.hpp"
|
||||
#include "Utility/HiveData.hpp"
|
||||
#include "Utility/Log.hpp"
|
||||
#include "Utility/Paths.hpp"
|
||||
#include "Utility/Signal.hpp"
|
||||
#include "Utility/Serialize.hpp"
|
||||
|
||||
#include <deque>
|
||||
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/textdlg.h>
|
||||
#include <wx/menu.h>
|
||||
#include <wx/msgdlg.h>
|
||||
|
||||
cHivesPanel::cHivesPanel(wxWindow* window)
|
||||
: wxPanel(window, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL),
|
||||
m_pWindow(window)
|
||||
{
|
||||
m_pMainSizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_pHivesSizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_pButtonSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
m_pAddHiveButton = new wxButton(this, SampleHive::ID::BC_HiveAdd, "+", wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_pAddHiveButton->SetToolTip(_("Create new hive"));
|
||||
|
||||
m_pButtonSizer->Add(m_pAddHiveButton, wxSizerFlags(1).Expand());
|
||||
|
||||
m_pRemoveHiveButton = new wxButton(this, SampleHive::ID::BC_HiveRemove, "-", wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_pRemoveHiveButton->SetToolTip(_("Delete selected hive"));
|
||||
|
||||
m_pButtonSizer->Add(m_pRemoveHiveButton, wxSizerFlags(1).Expand());
|
||||
|
||||
// Initializing wxDataViewTreeCtrl as another page of wxNotebook
|
||||
m_pHives = new wxDataViewTreeCtrl(this, SampleHive::ID::BC_Hives, wxDefaultPosition, wxDefaultSize, wxDV_NO_HEADER | wxDV_SINGLE);
|
||||
|
||||
m_pHivesSizer->Add(m_pHives, wxSizerFlags(1).Expand());
|
||||
|
||||
// Adding default hive
|
||||
m_FavoritesHive = m_pHives->AppendContainer(wxDataViewItem(wxNullPtr), _("Favorites"));
|
||||
|
||||
// Setting m_Hives to accept files to be dragged and dropped on it
|
||||
m_pHives->DragAcceptFiles(true);
|
||||
|
||||
m_pHives->Connect(wxEVT_DROP_FILES, wxDropFilesEventHandler(cHivesPanel::OnDragAndDropToHives), NULL, this);
|
||||
Bind(wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU, &cHivesPanel::OnShowHivesContextMenu, this, SampleHive::ID::BC_Hives);
|
||||
Bind(wxEVT_DATAVIEW_ITEM_START_EDITING, &cHivesPanel::OnHiveStartEditing, this, SampleHive::ID::BC_Hives);
|
||||
Bind(wxEVT_BUTTON, &cHivesPanel::OnClickAddHive, this, SampleHive::ID::BC_HiveAdd);
|
||||
Bind(wxEVT_BUTTON, &cHivesPanel::OnClickRemoveHive, this, SampleHive::ID::BC_HiveRemove);
|
||||
|
||||
m_pMainSizer->Add(m_pHivesSizer, wxSizerFlags(1).Expand());
|
||||
m_pMainSizer->Add(m_pButtonSizer, wxSizerFlags(0).Expand());
|
||||
|
||||
// Sizer for Hives page for wxNotebook
|
||||
this->SetSizer(m_pMainSizer);
|
||||
m_pMainSizer->Fit(this);
|
||||
m_pMainSizer->SetSizeHints(this);
|
||||
m_pMainSizer->Layout();
|
||||
}
|
||||
|
||||
void cHivesPanel::OnDragAndDropToHives(wxDropFilesEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
cDatabase db;
|
||||
|
||||
if (event.GetNumberOfFiles() > 0)
|
||||
{
|
||||
wxFileDataObject file_data;
|
||||
wxArrayString files;
|
||||
|
||||
wxDataViewItemArray items;
|
||||
int rows = SampleHive::cHiveData::Get().GetListCtrlSelections(items);
|
||||
|
||||
wxDataViewItem drop_target;;
|
||||
wxDataViewColumn* column;
|
||||
wxPoint position = event.GetPosition();
|
||||
|
||||
m_pHives->HitTest(position, drop_target, column);
|
||||
|
||||
wxString hive_name = m_pHives->GetItemText(drop_target);
|
||||
|
||||
wxString msg;
|
||||
|
||||
for (int i = 0; i < rows; i++)
|
||||
{
|
||||
int row = SampleHive::cHiveData::Get().GetListCtrlRowFromItem(items, i);
|
||||
|
||||
wxString name = SampleHive::cHiveData::Get().GetListCtrlTextValue(row, 1);
|
||||
|
||||
file_data.AddFile(name);
|
||||
|
||||
files = file_data.GetFilenames();
|
||||
|
||||
wxString file_name = serializer.DeserializeShowFileExtension() ?
|
||||
files[i].BeforeLast('.') : files[i];
|
||||
|
||||
SH_LOG_DEBUG("Dropping {} file(s) {} on {}", rows - i, files[i].ToStdString(), m_pHives->GetItemText(drop_target).ToStdString());
|
||||
|
||||
if (drop_target.IsOk() && m_pHives->IsContainer(drop_target) &&
|
||||
db.GetFavoriteColumnValueByFilename(file_name.ToStdString()) == 0)
|
||||
{
|
||||
m_pHives->AppendItem(drop_target, files[i]);
|
||||
|
||||
SampleHive::cHiveData::Get().ListCtrlSetVariant(wxVariant(wxBitmap(ICON_STAR_FILLED_16px, wxBITMAP_TYPE_PNG)), row, 0);
|
||||
|
||||
db.UpdateFavoriteColumn(file_name.ToStdString(), 1);
|
||||
db.UpdateHiveName(file_name.ToStdString(), hive_name.ToStdString());
|
||||
|
||||
msg = wxString::Format(_("%s added to %s."), files[i], hive_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (db.GetFavoriteColumnValueByFilename(file_name.ToStdString()) == 1)
|
||||
{
|
||||
wxMessageBox(wxString::Format(_("%s is already added to %s hive"), files[i],
|
||||
db.GetHiveByFilename(file_name.ToStdString())),
|
||||
_("Error!"), wxOK | wxICON_ERROR | wxCENTRE, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_pHives->GetItemText(drop_target) == "")
|
||||
wxMessageBox(_("Cannot drop item outside of a hive, try dropping on a hive."),
|
||||
_("Error!"), wxOK | wxICON_ERROR | wxCENTRE, this);
|
||||
else
|
||||
wxMessageBox(wxString::Format(_("%s is not a hive, try dropping on a hive."),
|
||||
m_pHives->GetItemText(drop_target)), _("Error!"),
|
||||
wxOK | wxICON_ERROR | wxCENTRE, this);
|
||||
}
|
||||
}
|
||||
|
||||
if (!msg.IsEmpty())
|
||||
SampleHive::cSignal::SendInfoBarMessage(msg, wxICON_ERROR, *this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cHivesPanel::OnShowHivesContextMenu(wxDataViewEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
cDatabase db;
|
||||
|
||||
wxDataViewItem selected_hive = event.GetItem();
|
||||
|
||||
wxString hive_name = m_pHives->GetItemText(selected_hive);
|
||||
|
||||
wxMenu menu;
|
||||
|
||||
if (m_pHives->IsContainer(selected_hive))
|
||||
{
|
||||
// Container menu items
|
||||
menu.Append(SampleHive::ID::MN_RenameHive, _("Rename hive"), _("Rename selected hive"));
|
||||
menu.Append(SampleHive::ID::MN_DeleteHive, _("Delete hive"), _("Delete selected hive"));
|
||||
|
||||
if (!m_bFiltered)
|
||||
menu.Append(SampleHive::ID::MN_FilterLibrary, _("Filter library"), _("Show only samples from current hive in library"));
|
||||
else
|
||||
menu.Append(SampleHive::ID::MN_FilterLibrary, _("Clear filter"), _("Clear the filter"));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Child menu items
|
||||
menu.Append(SampleHive::ID::MN_RemoveSample, _("Remove sample"), _("Remove the selected sample(s)"));
|
||||
menu.Append(SampleHive::ID::MN_ShowInLibrary, _("Show sample in library"), _("Show the selected in library"));
|
||||
}
|
||||
|
||||
if (selected_hive.IsOk() && m_pHives->IsContainer(selected_hive))
|
||||
{
|
||||
switch (m_pHives->GetPopupMenuSelectionFromUser(menu, event.GetPosition()))
|
||||
{
|
||||
case SampleHive::ID::MN_RenameHive:
|
||||
{
|
||||
std::deque<wxDataViewItem> nodes;
|
||||
nodes.push_back(m_pHives->GetNthChild(wxDataViewItem(wxNullPtr), 0));
|
||||
|
||||
wxDataViewItem current_item, found_item;
|
||||
|
||||
int row = 0;
|
||||
int hive_count = m_pHives->GetChildCount(wxDataViewItem(wxNullPtr));
|
||||
|
||||
wxString msg;
|
||||
|
||||
wxTextEntryDialog renameEntry(this, _("Enter new name"), wxGetTextFromUserPromptStr,
|
||||
wxEmptyString, wxTextEntryDialogStyle, wxDefaultPosition);
|
||||
|
||||
renameEntry.SetTextValidator(wxFILTER_EMPTY);
|
||||
|
||||
switch (renameEntry.ShowModal())
|
||||
{
|
||||
case wxID_OK:
|
||||
{
|
||||
wxString hive_name = renameEntry.GetValue();
|
||||
|
||||
while(!nodes.empty())
|
||||
{
|
||||
current_item = nodes.front();
|
||||
nodes.pop_front();
|
||||
|
||||
if (m_pHives->GetItemText(current_item) == hive_name)
|
||||
{
|
||||
found_item = current_item;
|
||||
SH_LOG_DEBUG("Found item: {}", m_pHives->GetItemText(current_item).ToStdString());
|
||||
break;
|
||||
}
|
||||
|
||||
wxDataViewItem child = m_pHives->GetNthChild(wxDataViewItem(wxNullPtr), 0);
|
||||
|
||||
while (row < (hive_count - 1))
|
||||
{
|
||||
row ++;
|
||||
|
||||
child = m_pHives->GetNthChild(wxDataViewItem(wxNullPtr), row);
|
||||
nodes.push_back(child);
|
||||
}
|
||||
}
|
||||
|
||||
nodes.clear();
|
||||
|
||||
if (found_item.IsOk())
|
||||
{
|
||||
wxMessageBox(wxString::Format(_("Another hive by the name %s already exist. "
|
||||
"Please try with a different name."), hive_name),
|
||||
_("Error!"), wxOK | wxCENTRE, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxString selected_hive_name = m_pHives->GetItemText(selected_hive);
|
||||
|
||||
int sample_count = m_pHives->GetChildCount(selected_hive);
|
||||
|
||||
if (sample_count <= 0)
|
||||
{
|
||||
m_pHives->SetItemText(selected_hive, hive_name);
|
||||
db.UpdateHive(selected_hive_name.ToStdString(), hive_name.ToStdString());
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < sample_count; i++)
|
||||
{
|
||||
wxDataViewItem sample_item = m_pHives->GetNthChild(selected_hive, i);
|
||||
|
||||
wxString sample_name = serializer.DeserializeShowFileExtension() ?
|
||||
m_pHives->GetItemText(sample_item).BeforeLast('.') :
|
||||
m_pHives->GetItemText(sample_item);
|
||||
|
||||
db.UpdateHiveName(sample_name.ToStdString(), hive_name.ToStdString());
|
||||
db.UpdateHive(selected_hive_name.ToStdString(), hive_name.ToStdString());
|
||||
|
||||
m_pHives->SetItemText(selected_hive, hive_name);
|
||||
}
|
||||
}
|
||||
|
||||
msg = wxString::Format(_("Successfully changed hive name to %s."), hive_name);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case wxID_CANCEL:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (!msg.IsEmpty())
|
||||
SampleHive::cSignal::SendInfoBarMessage(msg, wxICON_INFORMATION, *this);
|
||||
}
|
||||
break;
|
||||
case SampleHive::ID::MN_DeleteHive:
|
||||
{
|
||||
wxString msg;
|
||||
|
||||
wxMessageDialog deleteEmptyHiveDialog(this, wxString::Format(_("Are you sure you want to delete %s from hives?"),
|
||||
hive_name),
|
||||
wxMessageBoxCaptionStr,
|
||||
wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION | wxSTAY_ON_TOP);
|
||||
|
||||
wxMessageDialog deleteFilledHiveDialog(this, wxString::Format(_("Are you sure you want to delete %s and all samples "
|
||||
"inside %s from hives?"), hive_name, hive_name),
|
||||
wxMessageBoxCaptionStr,
|
||||
wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION | wxSTAY_ON_TOP);
|
||||
|
||||
if (hive_name == m_pHives->GetItemText(m_FavoritesHive))
|
||||
{
|
||||
wxMessageBox(wxString::Format(_("Error! Default hive %s cannot be deleted."), hive_name),
|
||||
_("Error!"), wxOK | wxCENTRE, this);
|
||||
return;
|
||||
}
|
||||
else if (!selected_hive.IsOk())
|
||||
{
|
||||
wxMessageBox(_("No hive selected, try selecting a hive first"), _("Error!"),
|
||||
wxOK | wxCENTRE, this);
|
||||
return;
|
||||
}
|
||||
else if (selected_hive.IsOk() && !m_pHives->IsContainer(selected_hive))
|
||||
{
|
||||
wxMessageBox(wxString::Format(_("Error! %s is not a hive, cannot delete from hives."), hive_name),
|
||||
_("Error!"), wxOK | wxCENTRE, this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pHives->GetChildCount(selected_hive) <= 0)
|
||||
{
|
||||
switch (deleteEmptyHiveDialog.ShowModal())
|
||||
{
|
||||
case wxID_YES:
|
||||
if (selected_hive.IsOk() && m_pHives->IsContainer(selected_hive) &&
|
||||
hive_name != m_pHives->GetItemText(m_FavoritesHive))
|
||||
{
|
||||
m_pHives->DeleteItem(selected_hive);
|
||||
|
||||
db.RemoveHiveFromDatabase(hive_name.ToStdString());
|
||||
|
||||
msg = wxString::Format(_("%s deleted from hives successfully."), hive_name);
|
||||
}
|
||||
break;
|
||||
case wxID_NO:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (deleteFilledHiveDialog.ShowModal())
|
||||
{
|
||||
case wxID_YES:
|
||||
if (selected_hive.IsOk() && m_pHives->IsContainer(selected_hive) &&
|
||||
hive_name != m_pHives->GetItemText(m_FavoritesHive))
|
||||
{
|
||||
wxDataViewItem child_item;
|
||||
|
||||
for (int i = 0; i < SampleHive::cHiveData::Get().GetListCtrlItemCount(); i++)
|
||||
{
|
||||
wxString matched_sample = serializer.DeserializeShowFileExtension() ?
|
||||
SampleHive::cHiveData::Get().GetListCtrlTextValue(i, 1).BeforeLast('.') :
|
||||
SampleHive::cHiveData::Get().GetListCtrlTextValue(i, 1);
|
||||
|
||||
for (int j = 0; j < m_pHives->GetChildCount(selected_hive); j++)
|
||||
{
|
||||
child_item = m_pHives->GetNthChild(selected_hive, j);
|
||||
|
||||
wxString child_name =
|
||||
serializer.DeserializeShowFileExtension() ?
|
||||
m_pHives->GetItemText(child_item).BeforeLast('.') :
|
||||
m_pHives->GetItemText(child_item);
|
||||
|
||||
if (child_name == matched_sample)
|
||||
{
|
||||
SH_LOG_DEBUG("Found match");
|
||||
|
||||
SampleHive::cHiveData::Get().ListCtrlSetVariant(wxVariant(wxBitmap(ICON_STAR_EMPTY_16px, wxBITMAP_TYPE_PNG)),
|
||||
i, 0);
|
||||
|
||||
db.UpdateFavoriteColumn(matched_sample.ToStdString(), 0);
|
||||
db.UpdateHiveName(matched_sample.ToStdString(),
|
||||
m_pHives->GetItemText(m_FavoritesHive).ToStdString());
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
SH_LOG_DEBUG("No match found");
|
||||
}
|
||||
}
|
||||
|
||||
m_pHives->DeleteChildren(selected_hive);
|
||||
m_pHives->DeleteItem(selected_hive);
|
||||
|
||||
db.RemoveHiveFromDatabase(hive_name.ToStdString());
|
||||
|
||||
msg = wxString::Format(_("%s and all samples inside %s have been deleted from hives successfully."),
|
||||
hive_name, hive_name);
|
||||
}
|
||||
break;
|
||||
case wxID_NO:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!msg.IsEmpty())
|
||||
SampleHive::cSignal::SendInfoBarMessage(msg, wxICON_INFORMATION, *this);
|
||||
}
|
||||
break;
|
||||
case SampleHive::ID::MN_FilterLibrary:
|
||||
{
|
||||
if (!m_bFiltered)
|
||||
{
|
||||
try
|
||||
{
|
||||
const auto dataset = db.FilterDatabaseByHiveName(hive_name.ToStdString(),
|
||||
serializer.DeserializeShowFileExtension(),
|
||||
ICON_STAR_FILLED_16px, ICON_STAR_EMPTY_16px);
|
||||
|
||||
if (dataset.empty())
|
||||
{
|
||||
wxMessageBox(_("Error! Database is empty."), _("Error!"),
|
||||
wxOK | wxICON_ERROR | wxCENTRE, this);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
SampleHive::cHiveData::Get().ListCtrlDeleteAllItems();
|
||||
|
||||
for (auto data : dataset)
|
||||
{
|
||||
SampleHive::cHiveData::Get().ListCtrlAppendItem(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
wxMessageBox(wxString::Format(_("Error loading data, cannot filter sample view. Error: %s"), e.what()),
|
||||
_("Error!"), wxOK | wxICON_ERROR | wxCENTRE, this);
|
||||
}
|
||||
|
||||
m_bFiltered = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
const auto dataset = db.FilterDatabaseBySampleName("", serializer.DeserializeShowFileExtension(),
|
||||
ICON_STAR_FILLED_16px, ICON_STAR_EMPTY_16px);
|
||||
|
||||
if (dataset.empty())
|
||||
{
|
||||
wxMessageBox(_("Error! Database is empty."), _("Error!"), wxOK | wxICON_ERROR | wxCENTRE, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
SampleHive::cHiveData::Get().ListCtrlDeleteAllItems();
|
||||
|
||||
for (auto data : dataset)
|
||||
{
|
||||
SampleHive::cHiveData::Get().ListCtrlAppendItem(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
wxMessageBox(wxString::Format(_("Error loading data, cannot filter sample view. Error: %s"), e.what()),
|
||||
_("Error!"), wxOK | wxICON_ERROR | wxCENTRE, this);
|
||||
}
|
||||
|
||||
m_bFiltered = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (selected_hive.IsOk() && !m_pHives->IsContainer(selected_hive))
|
||||
{
|
||||
switch (m_pHives->GetPopupMenuSelectionFromUser(menu, event.GetPosition()))
|
||||
{
|
||||
case SampleHive::ID::MN_RemoveSample:
|
||||
for (int i = 0; i < SampleHive::cHiveData::Get().GetListCtrlItemCount(); i++)
|
||||
{
|
||||
wxString matched_sample = serializer.DeserializeShowFileExtension() ?
|
||||
SampleHive::cHiveData::Get().GetListCtrlTextValue(i, 1).BeforeLast('.') :
|
||||
SampleHive::cHiveData::Get().GetListCtrlTextValue(i, 1);
|
||||
|
||||
wxString selected_sample_name = serializer.DeserializeShowFileExtension() ?
|
||||
m_pHives->GetItemText(event.GetItem()).BeforeLast('.') :
|
||||
m_pHives->GetItemText(event.GetItem());
|
||||
|
||||
if (selected_sample_name == matched_sample)
|
||||
{
|
||||
SH_LOG_DEBUG("Found match");
|
||||
|
||||
SampleHive::cHiveData::Get().ListCtrlSetVariant(wxVariant(wxBitmap(ICON_STAR_EMPTY_16px, wxBITMAP_TYPE_PNG)), i, 0);
|
||||
|
||||
db.UpdateFavoriteColumn(matched_sample.ToStdString(), 0);
|
||||
db.UpdateHiveName(matched_sample.ToStdString(), m_pHives->GetItemText(m_FavoritesHive).ToStdString());
|
||||
|
||||
m_pHives->DeleteItem(selected_hive);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
wxString msg = wxString::Format(_("Removed %s from %s"), m_pHives->GetItemText(event.GetItem()),
|
||||
db.GetHiveByFilename(matched_sample.ToStdString()));
|
||||
|
||||
SampleHive::cSignal::SendInfoBarMessage(msg, wxICON_INFORMATION, *this);
|
||||
}
|
||||
break;
|
||||
case SampleHive::ID::MN_ShowInLibrary:
|
||||
for (int i = 0; i < SampleHive::cHiveData::Get().GetListCtrlItemCount(); i++)
|
||||
{
|
||||
wxString matched_sample = serializer.DeserializeShowFileExtension() ?
|
||||
SampleHive::cHiveData::Get().GetListCtrlTextValue(i, 1).BeforeLast('.') :
|
||||
SampleHive::cHiveData::Get().GetListCtrlTextValue(i, 1);
|
||||
|
||||
wxString selected_sample_name = serializer.DeserializeShowFileExtension() ?
|
||||
m_pHives->GetItemText(event.GetItem()).BeforeLast('.') :
|
||||
m_pHives->GetItemText(event.GetItem());
|
||||
|
||||
if (selected_sample_name == matched_sample)
|
||||
{
|
||||
SH_LOG_DEBUG("Found match");
|
||||
|
||||
wxDataViewItem matched_item = SampleHive::cHiveData::Get().GetListCtrlItemFromRow(i);
|
||||
|
||||
SampleHive::cHiveData::Get().ListCtrlUnselectAllItems();
|
||||
SampleHive::cHiveData::Get().ListCtrlSelectRow(i);
|
||||
SampleHive::cHiveData::Get().ListCtrlEnsureVisible(matched_item);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cHivesPanel::OnHiveStartEditing(wxDataViewEvent &event)
|
||||
{
|
||||
SH_LOG_INFO("Right click on a hive and select rename to rename it..");
|
||||
event.Veto();
|
||||
}
|
||||
|
||||
void cHivesPanel::OnClickAddHive(wxCommandEvent& event)
|
||||
{
|
||||
cDatabase db;
|
||||
|
||||
std::deque<wxDataViewItem> nodes;
|
||||
nodes.push_back(m_pHives->GetNthChild(wxDataViewItem(wxNullPtr), 0));
|
||||
|
||||
wxDataViewItem current_item, found_item;
|
||||
|
||||
int row = 0;
|
||||
int hive_count = m_pHives->GetChildCount(wxDataViewItem(wxNullPtr));
|
||||
|
||||
wxString msg;
|
||||
|
||||
wxTextEntryDialog hiveEntry(this, _("Enter hive name"), _("Create new hive"), wxEmptyString,
|
||||
wxTextEntryDialogStyle, wxDefaultPosition);
|
||||
|
||||
hiveEntry.SetTextValidator(wxFILTER_EMPTY);
|
||||
|
||||
switch (hiveEntry.ShowModal())
|
||||
{
|
||||
case wxID_OK:
|
||||
{
|
||||
wxString hive_name = hiveEntry.GetValue();
|
||||
|
||||
while (!nodes.empty())
|
||||
{
|
||||
current_item = nodes.front();
|
||||
nodes.pop_front();
|
||||
|
||||
if (m_pHives->GetItemText(current_item) == hive_name)
|
||||
{
|
||||
found_item = current_item;
|
||||
SH_LOG_DEBUG("Found item: {}", m_pHives->GetItemText(current_item).ToStdString());
|
||||
break;
|
||||
}
|
||||
|
||||
wxDataViewItem child = m_pHives->GetNthChild(wxDataViewItem(wxNullPtr), 0);
|
||||
|
||||
while (row < (hive_count - 1))
|
||||
{
|
||||
row ++;
|
||||
|
||||
child = m_pHives->GetNthChild(wxDataViewItem(wxNullPtr), row);
|
||||
nodes.push_back(child);
|
||||
}
|
||||
}
|
||||
|
||||
nodes.clear();
|
||||
|
||||
if (found_item.IsOk())
|
||||
{
|
||||
wxMessageBox(wxString::Format(_("Another hive by the name %s already exist. Please try with a different name."),
|
||||
hive_name), _("Error!"), wxOK | wxCENTRE, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pHives->AppendContainer(wxDataViewItem(wxNullPtr), hive_name);
|
||||
db.InsertIntoHives(hive_name.ToStdString());
|
||||
|
||||
msg = wxString::Format(_("%s added to Hives."), hive_name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case wxID_CANCEL:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (!msg.IsEmpty())
|
||||
SampleHive::cSignal::SendInfoBarMessage(msg, wxICON_INFORMATION, *this);
|
||||
}
|
||||
|
||||
void cHivesPanel::OnClickRemoveHive(wxCommandEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
cDatabase db;
|
||||
|
||||
wxDataViewItem selected_item = m_pHives->GetSelection();
|
||||
wxString hive_name = m_pHives->GetItemText(selected_item);
|
||||
|
||||
wxString msg;
|
||||
|
||||
wxMessageDialog deleteEmptyHiveDialog(this, wxString::Format(_("Are you sure you want to delete %s from hives?"), hive_name),
|
||||
wxMessageBoxCaptionStr, wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION | wxSTAY_ON_TOP);
|
||||
|
||||
wxMessageDialog deleteFilledHiveDialog(this, wxString::Format(_("Are you sure you want to delete "
|
||||
"%s and all sample inside %s from hives?"), hive_name, hive_name),
|
||||
wxMessageBoxCaptionStr, wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION | wxSTAY_ON_TOP);
|
||||
|
||||
if (hive_name == m_pHives->GetItemText(m_FavoritesHive))
|
||||
{
|
||||
wxMessageBox(wxString::Format(_("Error! Default hive %s cannot be deleted."), hive_name), _("Error!"), wxOK | wxCENTRE, this);
|
||||
return;
|
||||
}
|
||||
else if (!selected_item.IsOk())
|
||||
{
|
||||
wxMessageBox(_("No hive selected, try selecting a hive first"), _("Error!"), wxOK | wxCENTRE, this);
|
||||
return;
|
||||
}
|
||||
else if (selected_item.IsOk() && !m_pHives->IsContainer(selected_item))
|
||||
{
|
||||
wxMessageBox(wxString::Format(_("Error! %s is not a hive, cannot delete from hives."), hive_name),
|
||||
_("Error!"), wxOK | wxCENTRE, this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pHives->GetChildCount(selected_item) <= 0)
|
||||
{
|
||||
switch (deleteEmptyHiveDialog.ShowModal())
|
||||
{
|
||||
case wxID_YES:
|
||||
if (selected_item.IsOk() && m_pHives->IsContainer(selected_item) &&
|
||||
hive_name != m_pHives->GetItemText(m_FavoritesHive))
|
||||
{
|
||||
m_pHives->DeleteItem(selected_item);
|
||||
|
||||
db.RemoveHiveFromDatabase(hive_name.ToStdString());
|
||||
msg = wxString::Format(_("%s deleted from hives successfully."), hive_name);
|
||||
}
|
||||
break;
|
||||
case wxID_NO:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (deleteFilledHiveDialog.ShowModal())
|
||||
{
|
||||
case wxID_YES:
|
||||
if (selected_item.IsOk() && m_pHives->IsContainer(selected_item) &&
|
||||
hive_name != m_pHives->GetItemText(m_FavoritesHive))
|
||||
{
|
||||
wxDataViewItem child_item;
|
||||
|
||||
for (int i = 0; i < SampleHive::cHiveData::Get().GetListCtrlItemCount(); i++)
|
||||
{
|
||||
wxString matched_sample = serializer.DeserializeShowFileExtension() ?
|
||||
SampleHive::cHiveData::Get().GetListCtrlTextValue(i, 1).BeforeLast('.') :
|
||||
SampleHive::cHiveData::Get().GetListCtrlTextValue(i, 1);
|
||||
|
||||
for (int j = 0; j < m_pHives->GetChildCount(selected_item); j++)
|
||||
{
|
||||
child_item = m_pHives->GetNthChild(selected_item, j);
|
||||
|
||||
wxString child_name = serializer.DeserializeShowFileExtension() ?
|
||||
m_pHives->GetItemText(child_item).BeforeLast('.') :
|
||||
m_pHives->GetItemText(child_item);
|
||||
|
||||
if (child_name == matched_sample)
|
||||
{
|
||||
SH_LOG_DEBUG("Found match");
|
||||
|
||||
SampleHive::cHiveData::Get().ListCtrlSetVariant(wxVariant(wxBitmap(ICON_STAR_EMPTY_16px, wxBITMAP_TYPE_PNG)), i, 0);
|
||||
|
||||
db.UpdateFavoriteColumn(matched_sample.ToStdString(), 0);
|
||||
db.UpdateHiveName(matched_sample.ToStdString(), m_pHives->GetItemText(m_FavoritesHive).ToStdString());
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
SH_LOG_DEBUG("No match found");
|
||||
}
|
||||
}
|
||||
|
||||
m_pHives->DeleteChildren(selected_item);
|
||||
m_pHives->DeleteItem(selected_item);
|
||||
|
||||
db.RemoveHiveFromDatabase(hive_name.ToStdString());
|
||||
|
||||
msg = wxString::Format(_("%s and all samples inside %s have been deleted from hives successfully."),
|
||||
hive_name, hive_name);
|
||||
}
|
||||
break;
|
||||
case wxID_NO:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!msg.IsEmpty())
|
||||
SampleHive::cSignal::SendInfoBarMessage(msg, wxICON_INFORMATION, *this);
|
||||
}
|
||||
|
||||
cHivesPanel::~cHivesPanel()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wx/button.h>
|
||||
#include <wx/dataview.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
class cHivesPanel : public wxPanel
|
||||
{
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
cHivesPanel(wxWindow* window);
|
||||
~cHivesPanel();
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
wxDataViewTreeCtrl* GetHivesObject() { return m_pHives; }
|
||||
wxDataViewItem& GetFavoritesHive() { return m_FavoritesHive; }
|
||||
|
||||
bool IsLibraryFiltered() { return m_bFiltered; }
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
// Hives panel button event handlers
|
||||
void OnDragAndDropToHives(wxDropFilesEvent& event);
|
||||
void OnClickAddHive(wxCommandEvent& event);
|
||||
void OnClickRemoveHive(wxCommandEvent& event);
|
||||
void OnShowHivesContextMenu(wxDataViewEvent& event);
|
||||
void OnHiveStartEditing(wxDataViewEvent& event);
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
wxDataViewItem m_FavoritesHive;
|
||||
|
||||
wxDataViewTreeCtrl* m_pHives = nullptr;
|
||||
wxButton* m_pAddHiveButton = nullptr;
|
||||
wxButton* m_pRemoveHiveButton = nullptr;
|
||||
wxBoxSizer* m_pMainSizer = nullptr;
|
||||
wxBoxSizer* m_pHivesSizer = nullptr;
|
||||
wxBoxSizer* m_pButtonSizer = nullptr;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
bool m_bFiltered = false;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
wxWindow* m_pWindow = nullptr;
|
||||
};
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "InfoBar.hpp"
|
||||
|
||||
cInfoBar::cInfoBar(wxWindow* window)
|
||||
: wxInfoBar(window)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
cInfoBar::~cInfoBar()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wx/infobar.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
class cInfoBar : public wxInfoBar
|
||||
{
|
||||
public:
|
||||
cInfoBar(wxWindow* window);
|
||||
~cInfoBar();
|
||||
|
||||
public:
|
||||
wxInfoBar* GetInfoBarObject() { return this; }
|
||||
|
||||
private:
|
||||
wxWindow* m_pWindow;
|
||||
};
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "GUI/Library.hpp"
|
||||
#include "Utility/Log.hpp"
|
||||
|
||||
cLibrary::cLibrary(wxWindow* window)
|
||||
: wxPanel(window, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL)
|
||||
{
|
||||
m_pSizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_pSearchBar = new cSearchBar(this);
|
||||
m_pInfoBar = new cInfoBar(this);
|
||||
m_pListCtrl = new cListCtrl(this);
|
||||
|
||||
m_pSizer->Add(m_pSearchBar, wxSizerFlags(1).Expand());
|
||||
m_pSizer->Add(m_pInfoBar, wxSizerFlags(0).Expand());
|
||||
m_pSizer->Add(m_pListCtrl, wxSizerFlags(1).Expand());
|
||||
|
||||
// Sizer for bottom right panel
|
||||
this->SetSizer(m_pSizer);
|
||||
m_pSizer->Fit(this);
|
||||
m_pSizer->SetSizeHints(this);
|
||||
m_pSizer->Layout();
|
||||
}
|
||||
|
||||
cLibrary::~cLibrary()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GUI/InfoBar.hpp"
|
||||
#include "GUI/ListCtrl.hpp"
|
||||
#include "GUI/SearchBar.hpp"
|
||||
|
||||
#include <wx/dataview.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/treectrl.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
class cLibrary : public wxPanel
|
||||
{
|
||||
public:
|
||||
cLibrary(wxWindow* window);
|
||||
~cLibrary();
|
||||
|
||||
public:
|
||||
wxSearchCtrl* GetSearchCtrlObject() const { return m_pSearchBar; }
|
||||
wxInfoBar* GetInfoBarObject() const { return m_pInfoBar; }
|
||||
wxDataViewListCtrl* GetListCtrlObject() const { return m_pListCtrl; }
|
||||
|
||||
private:
|
||||
cSearchBar* m_pSearchBar = nullptr;
|
||||
cInfoBar* m_pInfoBar = nullptr;
|
||||
cListCtrl* m_pListCtrl = nullptr;
|
||||
wxBoxSizer* m_pSizer = nullptr;
|
||||
};
|
||||
|
|
@ -0,0 +1,805 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "GUI/ListCtrl.hpp"
|
||||
#include "GUI/Dialogs/TagEditor.hpp"
|
||||
#include "Database/Database.hpp"
|
||||
#include "Utility/ControlIDs.hpp"
|
||||
#include "Utility/HiveData.hpp"
|
||||
#include "Utility/Serialize.hpp"
|
||||
#include "Utility/Event.hpp"
|
||||
#include "Utility/Signal.hpp"
|
||||
#include "Utility/Log.hpp"
|
||||
#include "Utility/Paths.hpp"
|
||||
#include "Utility/Utils.hpp"
|
||||
|
||||
#include <wx/dir.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/menu.h>
|
||||
#include <wx/progdlg.h>
|
||||
#include <wx/msgdlg.h>
|
||||
|
||||
cListCtrl::cListCtrl(wxWindow* window)
|
||||
: wxDataViewListCtrl(window, SampleHive::ID::BC_Library, wxDefaultPosition, wxDefaultSize,
|
||||
wxDV_MULTIPLE | wxDV_HORIZ_RULES | wxDV_VERT_RULES | wxDV_ROW_LINES),
|
||||
m_pWindow(window)
|
||||
{
|
||||
// Adding columns to wxDataViewListCtrl.
|
||||
AppendBitmapColumn(wxBitmap(ICON_STAR_FILLED_16px, wxBITMAP_TYPE_PNG),
|
||||
0,
|
||||
wxDATAVIEW_CELL_ACTIVATABLE,
|
||||
30,
|
||||
wxALIGN_CENTER,
|
||||
!wxDATAVIEW_COL_RESIZABLE);
|
||||
AppendTextColumn(_("Filename"),
|
||||
wxDATAVIEW_CELL_INERT,
|
||||
250,
|
||||
wxALIGN_LEFT,
|
||||
wxDATAVIEW_COL_RESIZABLE |
|
||||
wxDATAVIEW_COL_SORTABLE |
|
||||
wxDATAVIEW_COL_REORDERABLE);
|
||||
AppendTextColumn(_("Sample Pack"),
|
||||
wxDATAVIEW_CELL_INERT,
|
||||
180,
|
||||
wxALIGN_LEFT,
|
||||
wxDATAVIEW_COL_RESIZABLE |
|
||||
wxDATAVIEW_COL_SORTABLE |
|
||||
wxDATAVIEW_COL_REORDERABLE);
|
||||
AppendTextColumn(_("Type"),
|
||||
wxDATAVIEW_CELL_INERT,
|
||||
120,
|
||||
wxALIGN_LEFT,
|
||||
wxDATAVIEW_COL_RESIZABLE |
|
||||
wxDATAVIEW_COL_SORTABLE |
|
||||
wxDATAVIEW_COL_REORDERABLE);
|
||||
AppendTextColumn(_("Channels"),
|
||||
wxDATAVIEW_CELL_INERT,
|
||||
90,
|
||||
wxALIGN_RIGHT,
|
||||
wxDATAVIEW_COL_RESIZABLE |
|
||||
wxDATAVIEW_COL_SORTABLE |
|
||||
wxDATAVIEW_COL_REORDERABLE);
|
||||
AppendTextColumn(_("BPM"),
|
||||
wxDATAVIEW_CELL_INERT,
|
||||
80,
|
||||
wxALIGN_RIGHT,
|
||||
wxDATAVIEW_COL_RESIZABLE |
|
||||
wxDATAVIEW_COL_SORTABLE |
|
||||
wxDATAVIEW_COL_REORDERABLE);
|
||||
AppendTextColumn(_("Length"),
|
||||
wxDATAVIEW_CELL_INERT,
|
||||
80,
|
||||
wxALIGN_RIGHT,
|
||||
wxDATAVIEW_COL_RESIZABLE |
|
||||
wxDATAVIEW_COL_SORTABLE |
|
||||
wxDATAVIEW_COL_REORDERABLE);
|
||||
AppendTextColumn(_("Sample Rate"),
|
||||
wxDATAVIEW_CELL_INERT,
|
||||
120,
|
||||
wxALIGN_RIGHT,
|
||||
wxDATAVIEW_COL_RESIZABLE |
|
||||
wxDATAVIEW_COL_SORTABLE |
|
||||
wxDATAVIEW_COL_REORDERABLE);
|
||||
AppendTextColumn(_("Bitrate"),
|
||||
wxDATAVIEW_CELL_INERT,
|
||||
80,
|
||||
wxALIGN_RIGHT,
|
||||
wxDATAVIEW_COL_RESIZABLE |
|
||||
wxDATAVIEW_COL_SORTABLE |
|
||||
wxDATAVIEW_COL_REORDERABLE);
|
||||
AppendTextColumn(_("Path"),
|
||||
wxDATAVIEW_CELL_INERT,
|
||||
250,
|
||||
wxALIGN_LEFT,
|
||||
wxDATAVIEW_COL_RESIZABLE |
|
||||
wxDATAVIEW_COL_SORTABLE |
|
||||
wxDATAVIEW_COL_REORDERABLE);
|
||||
|
||||
// Enable cListCtrl to accept files to be dropped on it
|
||||
this->DragAcceptFiles(true);
|
||||
|
||||
// Enable dragging a file from cListCtrl
|
||||
this->EnableDragSource(wxDF_FILENAME);
|
||||
|
||||
Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, &cListCtrl::OnClickLibrary, this, SampleHive::ID::BC_Library);
|
||||
Bind(wxEVT_DATAVIEW_ITEM_ACTIVATED, &cListCtrl::OnDoubleClickLibrary, this, SampleHive::ID::BC_Library);
|
||||
Bind(wxEVT_DATAVIEW_ITEM_BEGIN_DRAG, &cListCtrl::OnDragFromLibrary, this);
|
||||
this->Connect(wxEVT_DROP_FILES, wxDropFilesEventHandler(cListCtrl::OnDragAndDropToLibrary), NULL, this);
|
||||
Bind(wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU, &cListCtrl::OnShowLibraryContextMenu, this, SampleHive::ID::BC_Library);
|
||||
Bind(wxEVT_DATAVIEW_COLUMN_HEADER_RIGHT_CLICK, &cListCtrl::OnShowLibraryColumnHeaderContextMenu, this, SampleHive::ID::BC_Library);
|
||||
}
|
||||
|
||||
void cListCtrl::OnClickLibrary(wxDataViewEvent& event)
|
||||
{
|
||||
cDatabase db;
|
||||
|
||||
int selected_row = this->ItemToRow(event.GetItem());
|
||||
int current_row = this->ItemToRow(this->GetCurrentItem());
|
||||
|
||||
if (selected_row < 0 || !event.GetItem().IsOk())
|
||||
return;
|
||||
|
||||
if (selected_row != current_row)
|
||||
{
|
||||
this->SetCurrentItem(event.GetItem());
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the waveform bitmap
|
||||
SampleHive::cSignal::SendWaveformUpdateStatus(*this);
|
||||
|
||||
// Update LoopAB button value
|
||||
SampleHive::cSignal::SendLoopABButtonValueChange(*this);
|
||||
|
||||
// Stop the timer
|
||||
SampleHive::cSignal::SendTimerStopStatus(*this);
|
||||
|
||||
wxString selection = this->GetTextValue(selected_row, 1);
|
||||
|
||||
// Get curremt column
|
||||
wxDataViewColumn* CurrentColumn = this->GetCurrentColumn();
|
||||
|
||||
// Get favorite column
|
||||
wxDataViewColumn* FavoriteColumn = this->GetColumn(0);
|
||||
|
||||
if (!CurrentColumn)
|
||||
return;
|
||||
|
||||
wxString sample_path = SampleHive::cUtils::Get().GetFilenamePathAndExtension(selection).Path;
|
||||
std::string filename = SampleHive::cUtils::Get().GetFilenamePathAndExtension(selection).Filename;
|
||||
std::string extension = SampleHive::cUtils::Get().GetFilenamePathAndExtension(selection).Extension;
|
||||
|
||||
if (CurrentColumn != FavoriteColumn)
|
||||
{
|
||||
// ClearLoopPoints();
|
||||
SampleHive::cSignal::SendClearLoopPointsStatus(*this);
|
||||
|
||||
// Play the sample
|
||||
SampleHive::cSignal::SendCallFunctionPlay(selection, true, *this);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxString msg;
|
||||
|
||||
// Get hive name and location
|
||||
std::string hive_name = SampleHive::cHiveData::Get().GetHiveItemText(true).ToStdString();
|
||||
wxDataViewItem hive_selection = SampleHive::cHiveData::Get().GetHiveItemSelection();
|
||||
|
||||
SH_LOG_DEBUG("HIVE NAME: {}", hive_name);
|
||||
|
||||
if (hive_selection.IsOk() && SampleHive::cHiveData::Get().IsHiveItemContainer(hive_selection))
|
||||
hive_name = SampleHive::cHiveData::Get().GetHiveItemText(false, hive_selection);
|
||||
|
||||
wxString name = this->GetTextValue(selected_row, 1);
|
||||
|
||||
// Get root
|
||||
wxDataViewItem root = wxDataViewItem(wxNullPtr);
|
||||
wxDataViewItem container;
|
||||
wxDataViewItem child;
|
||||
|
||||
if (db.GetFavoriteColumnValueByFilename(filename) == 0)
|
||||
{
|
||||
this->SetValue(wxVariant(wxBitmap(ICON_STAR_FILLED_16px, wxBITMAP_TYPE_PNG)), selected_row, 0);
|
||||
|
||||
db.UpdateFavoriteColumn(filename, 1);
|
||||
db.UpdateHiveName(filename, hive_name);
|
||||
|
||||
for (int i = 0; i < SampleHive::cHiveData::Get().GetHiveChildCount(root); i++)
|
||||
{
|
||||
container = SampleHive::cHiveData::Get().GetHiveNthChild(root, i);
|
||||
|
||||
if (SampleHive::cHiveData::Get().GetHiveItemText(false, container) == hive_name)
|
||||
{
|
||||
SampleHive::cHiveData::Get().HiveAppendItem(container, name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
msg = wxString::Format(_("Added %s to %s"), name, hive_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->SetValue(wxVariant(wxBitmap(ICON_STAR_EMPTY_16px, wxBITMAP_TYPE_PNG)), selected_row, 0);
|
||||
|
||||
db.UpdateFavoriteColumn(filename, 0);
|
||||
db.UpdateHiveName(filename, SampleHive::cHiveData::Get().GetHiveItemText(true).ToStdString());
|
||||
|
||||
for (int i = 0; i < SampleHive::cHiveData::Get().GetHiveChildCount(root); i++)
|
||||
{
|
||||
container = SampleHive::cHiveData::Get().GetHiveNthChild(root, i);
|
||||
|
||||
for (int j = 0; j < SampleHive::cHiveData::Get().GetHiveChildCount(container); j++)
|
||||
{
|
||||
child = SampleHive::cHiveData::Get().GetHiveNthChild(container, j);
|
||||
|
||||
if (SampleHive::cHiveData::Get().GetHiveItemText(false, child) == name)
|
||||
{
|
||||
SampleHive::cHiveData::Get().HiveDeleteItem(child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
msg = wxString::Format(_("Removed %s from %s"), name, hive_name);
|
||||
}
|
||||
|
||||
if (!msg.IsEmpty())
|
||||
SampleHive::cSignal::SendInfoBarMessage(msg, wxICON_INFORMATION, *this);
|
||||
}
|
||||
}
|
||||
|
||||
void cListCtrl::OnDoubleClickLibrary(wxDataViewEvent& event)
|
||||
{
|
||||
cDatabase db;
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
int selected_row = this->ItemToRow(event.GetItem());
|
||||
int current_row = this->ItemToRow(this->GetCurrentItem());
|
||||
|
||||
if (selected_row < 0 || !event.GetItem().IsOk())
|
||||
return;
|
||||
|
||||
if (selected_row != current_row)
|
||||
{
|
||||
this->SetCurrentItem(event.GetItem());
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the waveform bitmap
|
||||
SampleHive::cSignal::SendWaveformUpdateStatus(*this);
|
||||
|
||||
// Update LoopAB button value
|
||||
SampleHive::cSignal::SendLoopABButtonValueChange(*this);
|
||||
|
||||
// Stop the timer
|
||||
SampleHive::cSignal::SendTimerStopStatus(*this);
|
||||
|
||||
wxString selection = this->GetTextValue(selected_row, 1);
|
||||
|
||||
// Get curremt column
|
||||
wxDataViewColumn* CurrentColumn = this->GetCurrentColumn();
|
||||
|
||||
// Get favorite column
|
||||
wxDataViewColumn* FavoriteColumn = this->GetColumn(0);
|
||||
|
||||
if (!CurrentColumn)
|
||||
return;
|
||||
|
||||
if (CurrentColumn != FavoriteColumn)
|
||||
{
|
||||
// ClearLoopPoints();
|
||||
SampleHive::cSignal::SendClearLoopPointsStatus(*this);
|
||||
|
||||
// Play the sample
|
||||
if (serializer.DeserializeDoubleClickToPlay())
|
||||
SampleHive::cSignal::SendCallFunctionPlay(selection, false, *this);
|
||||
}
|
||||
}
|
||||
|
||||
void cListCtrl::OnDragAndDropToLibrary(wxDropFilesEvent& event)
|
||||
{
|
||||
SH_LOG_DEBUG("Start Inserting Samples");
|
||||
|
||||
if (event.GetNumberOfFiles() > 0)
|
||||
{
|
||||
wxString* dropped = event.GetFiles();
|
||||
wxASSERT(dropped);
|
||||
|
||||
wxBusyCursor busy_cursor;
|
||||
wxWindowDisabler window_disabler;
|
||||
|
||||
wxString name;
|
||||
wxString filepath;
|
||||
wxArrayString filepath_array;
|
||||
|
||||
wxProgressDialog* progressDialog = new wxProgressDialog(_("Reading files.."),
|
||||
_("Reading files, please wait..."),
|
||||
event.GetNumberOfFiles(), this,
|
||||
wxPD_APP_MODAL | wxPD_SMOOTH |
|
||||
wxPD_CAN_ABORT | wxPD_AUTO_HIDE);
|
||||
|
||||
progressDialog->CenterOnParent(wxBOTH);
|
||||
|
||||
wxYield();
|
||||
|
||||
for (int i = 0; i < event.GetNumberOfFiles(); i++)
|
||||
{
|
||||
filepath = dropped[i];
|
||||
|
||||
if (wxFileExists(filepath))
|
||||
{
|
||||
filepath_array.push_back(filepath);
|
||||
}
|
||||
else if (wxDirExists(filepath))
|
||||
{
|
||||
wxDir::GetAllFiles(filepath, &filepath_array);
|
||||
}
|
||||
|
||||
progressDialog->Pulse(_("Reading Samples"), NULL);
|
||||
}
|
||||
|
||||
progressDialog->Destroy();
|
||||
|
||||
SampleHive::cUtils::Get().AddSamples(filepath_array, m_pWindow);
|
||||
|
||||
SH_LOG_DEBUG("Done Inserting Samples");
|
||||
}
|
||||
}
|
||||
|
||||
void cListCtrl::OnDragFromLibrary(wxDataViewEvent& event)
|
||||
{
|
||||
int selected_row = this->ItemToRow(event.GetItem());
|
||||
|
||||
if (selected_row < 0)
|
||||
return;
|
||||
|
||||
wxString selection = this->GetTextValue(selected_row, 1);
|
||||
|
||||
wxString sample_path = SampleHive::cUtils::Get().GetFilenamePathAndExtension(selection).Path;
|
||||
|
||||
wxFileDataObject* fileData = new wxFileDataObject();
|
||||
|
||||
fileData->AddFile(sample_path);
|
||||
event.SetDataObject(fileData);
|
||||
|
||||
SH_LOG_DEBUG("Started dragging '{}'.", sample_path.ToStdString());
|
||||
}
|
||||
|
||||
void cListCtrl::OnShowLibraryContextMenu(wxDataViewEvent& event)
|
||||
{
|
||||
cTagEditor* tagEditor;
|
||||
cDatabase db;
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
wxString msg;
|
||||
|
||||
wxDataViewItem item = event.GetItem();
|
||||
int selected_row;
|
||||
|
||||
if (item.IsOk())
|
||||
selected_row = this->ItemToRow(item);
|
||||
else
|
||||
return;
|
||||
|
||||
wxString selection = this->GetTextValue(selected_row, 1);
|
||||
|
||||
wxString sample_path = SampleHive::cUtils::Get().GetFilenamePathAndExtension(selection).Path;
|
||||
std::string filename = SampleHive::cUtils::Get().GetFilenamePathAndExtension(selection).Filename;
|
||||
std::string extension = SampleHive::cUtils::Get().GetFilenamePathAndExtension(selection).Extension;
|
||||
|
||||
wxMenu menu;
|
||||
|
||||
//true = add false = remove
|
||||
bool favorite_add = false;
|
||||
|
||||
if (db.GetFavoriteColumnValueByFilename(filename) == 1)
|
||||
menu.Append(SampleHive::ID::MN_FavoriteSample, _("Remove from hive"), _("Remove the selected sample(s) from hive"));
|
||||
else
|
||||
{
|
||||
menu.Append(SampleHive::ID::MN_FavoriteSample, _("Add to hive"), _("Add selected sample(s) to hive"));
|
||||
favorite_add = true;
|
||||
}
|
||||
|
||||
menu.Append(SampleHive::ID::MN_DeleteSample, _("Delete"), _("Delete the selected sample(s) from database"));
|
||||
menu.Append(SampleHive::ID::MN_TrashSample, _("Trash"), _("Send the selected sample(s) to trash"));
|
||||
|
||||
if (this->GetSelectedItemsCount() <= 1)
|
||||
{
|
||||
menu.Append(SampleHive::ID::MN_EditTagSample, _("Edit tags"),
|
||||
_("Edit the tags for the selected sample"))->Enable(true);
|
||||
menu.Append(SampleHive::ID::MN_OpenFile, _("Open in file manager"),
|
||||
_("Open the selected sample in system's file manager"))->Enable(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
menu.Append(SampleHive::ID::MN_EditTagSample, _("Edit tags"),
|
||||
_("Edit the tags for the selected sample"))->Enable(false);
|
||||
menu.Append(SampleHive::ID::MN_OpenFile, _("Open in file manager"),
|
||||
_("Open the selected sample in system's file manager"))->Enable(false);
|
||||
}
|
||||
|
||||
switch (this->GetPopupMenuSelectionFromUser(menu, event.GetPosition()))
|
||||
{
|
||||
case SampleHive::ID::MN_FavoriteSample:
|
||||
{
|
||||
std::string hive_name = SampleHive::cHiveData::Get().GetHiveItemText(true).ToStdString();
|
||||
|
||||
wxDataViewItem hive_selection = SampleHive::cHiveData::Get().GetHiveItemSelection();
|
||||
|
||||
if (hive_selection.IsOk() && SampleHive::cHiveData::Get().IsHiveItemContainer(hive_selection))
|
||||
hive_name = SampleHive::cHiveData::Get().GetHiveItemText(false, hive_selection);
|
||||
|
||||
wxDataViewItem root = wxDataViewItem(wxNullPtr);
|
||||
wxDataViewItem container;
|
||||
wxDataViewItem child;
|
||||
|
||||
wxDataViewItemArray samples;
|
||||
int sample_count = this->GetSelections(samples);
|
||||
int selected_row = 0;
|
||||
int db_status = 0;
|
||||
|
||||
for (int k = 0; k < sample_count; k++)
|
||||
{
|
||||
selected_row = this->ItemToRow(samples[k]);
|
||||
|
||||
if (selected_row < 0)
|
||||
continue;
|
||||
|
||||
wxString name = this->GetTextValue(selected_row, 1);
|
||||
|
||||
filename = serializer.DeserializeShowFileExtension() ?
|
||||
name.BeforeLast('.').ToStdString() : name.ToStdString();
|
||||
|
||||
db_status = db.GetFavoriteColumnValueByFilename(filename);
|
||||
|
||||
// Aleady Added, Do Nothing
|
||||
if (favorite_add && db_status == 1)
|
||||
continue;
|
||||
|
||||
// Already Removed, Do Nothing
|
||||
if (!favorite_add && db_status == 0)
|
||||
continue;
|
||||
|
||||
// Add To Favorites
|
||||
if (favorite_add && db_status == 0)
|
||||
{
|
||||
this->SetValue(wxVariant(wxBitmap(ICON_STAR_FILLED_16px, wxBITMAP_TYPE_PNG)), selected_row, 0);
|
||||
|
||||
db.UpdateFavoriteColumn(filename, 1);
|
||||
db.UpdateHiveName(filename, hive_name);
|
||||
|
||||
for (int i = 0; i < SampleHive::cHiveData::Get().GetHiveChildCount(root); i++)
|
||||
{
|
||||
container = SampleHive::cHiveData::Get().GetHiveNthChild(root, i);
|
||||
|
||||
if (SampleHive::cHiveData::Get().GetHiveItemText(false, container) == hive_name)
|
||||
{
|
||||
SampleHive::cHiveData::Get().HiveAppendItem(container, name);
|
||||
|
||||
msg = wxString::Format(_("Added %s to %s"), name, hive_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Remove From Favorites
|
||||
this->SetValue(wxVariant(wxBitmap(ICON_STAR_EMPTY_16px, wxBITMAP_TYPE_PNG)), selected_row, 0);
|
||||
|
||||
db.UpdateFavoriteColumn(filename, 0);
|
||||
db.UpdateHiveName(filename, SampleHive::cHiveData::Get().GetHiveItemText(true).ToStdString());
|
||||
|
||||
for (int i = 0; i < SampleHive::cHiveData::Get().GetHiveChildCount(root); i++)
|
||||
{
|
||||
container = SampleHive::cHiveData::Get().GetHiveNthChild(root, i);
|
||||
|
||||
for (int j = 0; j < SampleHive::cHiveData::Get().GetHiveChildCount(container); j++)
|
||||
{
|
||||
child = SampleHive::cHiveData::Get().GetHiveNthChild(container, j);
|
||||
|
||||
if (SampleHive::cHiveData::Get().GetHiveItemText(false, child) == name)
|
||||
{
|
||||
SampleHive::cHiveData::Get().HiveDeleteItem(child);
|
||||
|
||||
msg = wxString::Format(_("Removed %s from %s"), name, hive_name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case SampleHive::ID::MN_DeleteSample:
|
||||
{
|
||||
wxDataViewItemArray items;
|
||||
int rows = this->GetSelections(items);
|
||||
|
||||
wxMessageDialog singleMsgDialog(this, wxString::Format(_("Are you sure you want to delete %s from database? "
|
||||
"Warning this change is permanent, and cannot be undone."),
|
||||
sample_path.AfterLast('/')),
|
||||
wxMessageBoxCaptionStr,
|
||||
wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION | wxSTAY_ON_TOP | wxCENTER);
|
||||
|
||||
wxMessageDialog multipleMsgDialog(this, wxString::Format(_("Are you sure you want to delete "
|
||||
"%d selected samples from database? Warning this change is "
|
||||
"permanent, and cannot be undone."), rows),
|
||||
wxMessageBoxCaptionStr,
|
||||
wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION | wxSTAY_ON_TOP | wxCENTER);
|
||||
|
||||
wxDataViewItem root = wxDataViewItem(wxNullPtr);
|
||||
wxDataViewItem container;
|
||||
wxDataViewItem child;
|
||||
|
||||
if (this->GetSelectedItemsCount() <= 1)
|
||||
{
|
||||
switch (singleMsgDialog.ShowModal())
|
||||
{
|
||||
case wxID_YES:
|
||||
{
|
||||
db.RemoveSampleFromDatabase(filename);
|
||||
this->DeleteItem(selected_row);
|
||||
|
||||
for (int j = 0; j < SampleHive::cHiveData::Get().GetHiveChildCount(root); j++)
|
||||
{
|
||||
container = SampleHive::cHiveData::Get().GetHiveNthChild(root, j);
|
||||
|
||||
for (int k = 0; k < SampleHive::cHiveData::Get().GetHiveChildCount(container); k++)
|
||||
{
|
||||
child = SampleHive::cHiveData::Get().GetHiveNthChild(container, k);
|
||||
|
||||
wxString child_text = serializer.DeserializeShowFileExtension() ?
|
||||
SampleHive::cHiveData::Get().GetHiveItemText(false, child).BeforeLast('.') :
|
||||
SampleHive::cHiveData::Get().GetHiveItemText(false, child);
|
||||
|
||||
if (child_text == filename)
|
||||
{
|
||||
SampleHive::cHiveData::Get().HiveDeleteItem(child);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
msg = wxString::Format(_("Deleted %s from database successfully"), selection);
|
||||
}
|
||||
break;
|
||||
case wxID_NO:
|
||||
msg = _("Cancel delete");
|
||||
break;
|
||||
default:
|
||||
wxMessageBox(_("Unexpected wxMessageDialog return code!"), _("Error!"),
|
||||
wxOK | wxICON_ERROR | wxCENTRE, this);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (multipleMsgDialog.ShowModal())
|
||||
{
|
||||
case wxID_YES:
|
||||
{
|
||||
for (int i = 0; i < rows; i++)
|
||||
{
|
||||
int row = this->ItemToRow(items[i]);
|
||||
|
||||
wxString text_value = this->GetTextValue(row, 1);
|
||||
|
||||
std::string multi_selection = serializer.DeserializeShowFileExtension() ?
|
||||
text_value.BeforeLast('.').ToStdString() : text_value.ToStdString() ;
|
||||
|
||||
db.RemoveSampleFromDatabase(multi_selection);
|
||||
this->DeleteItem(row);
|
||||
|
||||
for (int j = 0; j < SampleHive::cHiveData::Get().GetHiveChildCount(root); j++)
|
||||
{
|
||||
container = SampleHive::cHiveData::Get().GetHiveNthChild(root, j);
|
||||
|
||||
for (int k = 0; k < SampleHive::cHiveData::Get().GetHiveChildCount(container); k++)
|
||||
{
|
||||
child = SampleHive::cHiveData::Get().GetHiveNthChild(container, k);
|
||||
|
||||
wxString child_text = serializer.DeserializeShowFileExtension() ?
|
||||
SampleHive::cHiveData::Get().GetHiveItemText(false, child).BeforeLast('.') :
|
||||
SampleHive::cHiveData::Get().GetHiveItemText(false, child);
|
||||
|
||||
if (child_text == multi_selection)
|
||||
{
|
||||
SampleHive::cHiveData::Get().HiveDeleteItem(child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
msg = wxString::Format(_("Deleted %s from database successfully"), text_value);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case wxID_NO:
|
||||
msg = _("Cancel delete");
|
||||
break;
|
||||
default:
|
||||
wxMessageBox(_("Unexpected wxMessageDialog return code!"), _("Error!"),
|
||||
wxOK | wxICON_ERROR | wxCENTRE, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SampleHive::ID::MN_TrashSample:
|
||||
{
|
||||
wxDataViewItem root = wxDataViewItem(wxNullPtr);
|
||||
wxDataViewItem container, child;
|
||||
|
||||
if (db.IsTrashed(filename))
|
||||
SH_LOG_INFO("{} already trashed", filename);
|
||||
else
|
||||
{
|
||||
wxDataViewItemArray items;
|
||||
int rows = this->GetSelections(items);
|
||||
|
||||
wxString name;
|
||||
wxFileDataObject file_data;
|
||||
wxArrayString files;
|
||||
|
||||
for (int i = 0; i < rows; i++)
|
||||
{
|
||||
int item_row = this->ItemToRow(items[i]);
|
||||
|
||||
wxString text_value = this->GetTextValue(item_row, 1);
|
||||
|
||||
std::string multi_selection = serializer.DeserializeShowFileExtension() ?
|
||||
this->GetTextValue(item_row, 1).BeforeLast('.').ToStdString() :
|
||||
this->GetTextValue(item_row, 1).ToStdString() ;
|
||||
|
||||
file_data.AddFile(multi_selection);
|
||||
|
||||
files = file_data.GetFilenames();
|
||||
|
||||
if (db.GetFavoriteColumnValueByFilename(files[i].ToStdString()))
|
||||
{
|
||||
this->SetValue(wxVariant(wxBitmap(ICON_STAR_EMPTY_16px, wxBITMAP_TYPE_PNG)), item_row, 0);
|
||||
|
||||
db.UpdateFavoriteColumn(files[i].ToStdString(), 0);
|
||||
|
||||
for (int j = 0; j < SampleHive::cHiveData::Get().GetHiveChildCount(root); j++)
|
||||
{
|
||||
container = SampleHive::cHiveData::Get().GetHiveNthChild(root, j);
|
||||
|
||||
for (int k = 0; k < SampleHive::cHiveData::Get().GetHiveChildCount(container); k++)
|
||||
{
|
||||
child = SampleHive::cHiveData::Get().GetHiveNthChild(container, k);
|
||||
|
||||
wxString child_text = serializer.DeserializeShowFileExtension() ?
|
||||
SampleHive::cHiveData::Get().GetHiveItemText(false, child).BeforeLast('.') :
|
||||
SampleHive::cHiveData::Get().GetHiveItemText(false, child);
|
||||
|
||||
if (child_text == files[i])
|
||||
{
|
||||
SampleHive::cHiveData::Get().HiveDeleteItem(child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SampleHive::cHiveData::Get().TrashAppendItem(SampleHive::cHiveData::Get().GetTrashRoot(), text_value);
|
||||
|
||||
this->DeleteItem(item_row);
|
||||
|
||||
db.UpdateTrashColumn(files[i].ToStdString(), 1);
|
||||
db.UpdateHiveName(files[i].ToStdString(), SampleHive::cHiveData::Get().GetHiveItemText(true).ToStdString());
|
||||
|
||||
msg = wxString::Format(_("%s sent to trash"), text_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SampleHive::ID::MN_EditTagSample:
|
||||
{
|
||||
tagEditor = new cTagEditor(this, static_cast<std::string>(sample_path));
|
||||
|
||||
switch (tagEditor->ShowModal())
|
||||
{
|
||||
case wxID_OK:
|
||||
SH_LOG_DEBUG("tags dialog ok, Return code: {}", tagEditor->GetReturnCode());
|
||||
break;
|
||||
case wxID_APPLY:
|
||||
SH_LOG_DEBUG("tags dialog apply, Return code: {}", tagEditor->GetReturnCode());
|
||||
break;
|
||||
case wxID_CANCEL:
|
||||
SH_LOG_DEBUG("tags dialog cancel, Return code: {}", tagEditor->GetReturnCode());
|
||||
break;
|
||||
default:
|
||||
msg = _("Unexpected TagEditor return code!");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SampleHive::ID::MN_OpenFile:
|
||||
wxExecute(wxString::Format("xdg-open '%s'", sample_path.BeforeLast('/')));
|
||||
break;
|
||||
case wxID_NONE:
|
||||
return;
|
||||
default:
|
||||
wxMessageBox(_("Unexpected wxMenu return code!"), _("Error!"),
|
||||
wxOK | wxICON_ERROR | wxCENTRE, this);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!msg.IsEmpty())
|
||||
SampleHive::cSignal::SendInfoBarMessage(msg, wxICON_INFORMATION, *this);
|
||||
}
|
||||
|
||||
void cListCtrl::OnShowLibraryColumnHeaderContextMenu(wxDataViewEvent& event)
|
||||
{
|
||||
wxMenu menu;
|
||||
|
||||
wxDataViewColumn* FavoriteColumn = this->GetColumn(0);
|
||||
wxDataViewColumn* FilenameColumn = this->GetColumn(1);
|
||||
wxDataViewColumn* SamplePackColumn = this->GetColumn(2);
|
||||
wxDataViewColumn* TypeColumn = this->GetColumn(3);
|
||||
wxDataViewColumn* ChannelsColumn = this->GetColumn(4);
|
||||
wxDataViewColumn* BpmColumn = this->GetColumn(5);
|
||||
wxDataViewColumn* LengthColumn = this->GetColumn(6);
|
||||
wxDataViewColumn* SampleRateColumn = this->GetColumn(7);
|
||||
wxDataViewColumn* BitrateColumn = this->GetColumn(8);
|
||||
wxDataViewColumn* PathColumn = this->GetColumn(9);
|
||||
|
||||
menu.AppendCheckItem(SampleHive::ID::MN_ColumnFavorite, _("Favorites"),
|
||||
_("Toggle favorites column"))->Check(FavoriteColumn->IsShown());
|
||||
menu.AppendCheckItem(SampleHive::ID::MN_ColumnFilename, _("Filename"),
|
||||
_("Toggle filename column"))->Check(FilenameColumn->IsShown());
|
||||
menu.AppendCheckItem(SampleHive::ID::MN_ColumnSamplePack, _("Sample Pack"),
|
||||
_("Toggle sample pack column"))->Check(SamplePackColumn->IsShown());
|
||||
menu.AppendCheckItem(SampleHive::ID::MN_ColumnType, _("Type"),
|
||||
_("Toggle type column"))->Check(TypeColumn->IsShown());
|
||||
menu.AppendCheckItem(SampleHive::ID::MN_ColumnChannels, _("Channels"),
|
||||
_("Toggle channels column"))->Check(ChannelsColumn->IsShown());
|
||||
menu.AppendCheckItem(SampleHive::ID::MN_ColumnBPM, _("BPM"),
|
||||
_("Toggle length column"))->Check(BpmColumn->IsShown());
|
||||
menu.AppendCheckItem(SampleHive::ID::MN_ColumnLength, _("Length"),
|
||||
_("Toggle length column"))->Check(LengthColumn->IsShown());
|
||||
menu.AppendCheckItem(SampleHive::ID::MN_ColumnSampleRate, _("Sample Rate"),
|
||||
_("Toggle sample rate column"))->Check(SampleRateColumn->IsShown());
|
||||
menu.AppendCheckItem(SampleHive::ID::MN_ColumnBitrate, _("Bitrate"),
|
||||
_("Toggle bitrate column"))->Check(BitrateColumn->IsShown());
|
||||
menu.AppendCheckItem(SampleHive::ID::MN_ColumnPath, _("Path"),
|
||||
_("Toggle path column"))->Check(PathColumn->IsShown());
|
||||
|
||||
switch (this->GetPopupMenuSelectionFromUser(menu, event.GetPosition()))
|
||||
{
|
||||
case SampleHive::ID::MN_ColumnFavorite:
|
||||
FavoriteColumn->SetHidden(!menu.IsChecked(SampleHive::ID::MN_ColumnFavorite));
|
||||
break;
|
||||
case SampleHive::ID::MN_ColumnFilename:
|
||||
FilenameColumn->SetHidden(!menu.IsChecked(SampleHive::ID::MN_ColumnFilename));
|
||||
break;
|
||||
case SampleHive::ID::MN_ColumnSamplePack:
|
||||
SamplePackColumn->SetHidden(!menu.IsChecked(SampleHive::ID::MN_ColumnSamplePack));
|
||||
break;
|
||||
case SampleHive::ID::MN_ColumnType:
|
||||
TypeColumn->SetHidden(!menu.IsChecked(SampleHive::ID::MN_ColumnType));
|
||||
break;
|
||||
case SampleHive::ID::MN_ColumnChannels:
|
||||
ChannelsColumn->SetHidden(!menu.IsChecked(SampleHive::ID::MN_ColumnChannels));
|
||||
break;
|
||||
case SampleHive::ID::MN_ColumnBPM:
|
||||
BpmColumn->SetHidden(!menu.IsChecked(SampleHive::ID::MN_ColumnBPM));
|
||||
break;
|
||||
case SampleHive::ID::MN_ColumnLength:
|
||||
LengthColumn->SetHidden(!menu.IsChecked(SampleHive::ID::MN_ColumnLength));
|
||||
break;
|
||||
case SampleHive::ID::MN_ColumnSampleRate:
|
||||
SampleRateColumn->SetHidden(!menu.IsChecked(SampleHive::ID::MN_ColumnSampleRate));
|
||||
break;
|
||||
case SampleHive::ID::MN_ColumnBitrate:
|
||||
BitrateColumn->SetHidden(!menu.IsChecked(SampleHive::ID::MN_ColumnBitrate));
|
||||
break;
|
||||
case SampleHive::ID::MN_ColumnPath:
|
||||
PathColumn->SetHidden(!menu.IsChecked(SampleHive::ID::MN_ColumnPath));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cListCtrl::~cListCtrl()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -20,46 +20,32 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <wx/dataview.h>
|
||||
#include <wx/treectrl.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
#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
|
||||
class cListCtrl : public wxDataViewListCtrl
|
||||
{
|
||||
public:
|
||||
Tags(const std::string& filepath);
|
||||
~Tags();
|
||||
// -------------------------------------------------------------------
|
||||
cListCtrl(wxWindow* window);
|
||||
~cListCtrl();
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
wxDataViewListCtrl* GetListCtrlObject() { return this; }
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
const std::string& m_Filepath;
|
||||
// Library event handlers
|
||||
void OnClickLibrary(wxDataViewEvent& event);
|
||||
void OnDoubleClickLibrary(wxDataViewEvent& event);
|
||||
void OnDragAndDropToLibrary(wxDropFilesEvent& event);
|
||||
void OnDragFromLibrary(wxDataViewEvent& event);
|
||||
void OnShowLibraryContextMenu(wxDataViewEvent& event);
|
||||
void OnShowLibraryColumnHeaderContextMenu(wxDataViewEvent& event);
|
||||
|
||||
bool bValid = false;
|
||||
|
||||
public:
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
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; }
|
||||
wxWindow* m_pWindow = nullptr;
|
||||
};
|
||||
|
|
@ -0,0 +1,978 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "GUI/MainFrame.hpp"
|
||||
#include "GUI/Dialogs/Settings.hpp"
|
||||
#include "Database/Database.hpp"
|
||||
#include "Utility/ControlIDs.hpp"
|
||||
#include "Utility/HiveData.hpp"
|
||||
#include "Utility/Log.hpp"
|
||||
#include "Utility/Paths.hpp"
|
||||
#include "Utility/Utils.hpp"
|
||||
#include "SampleHiveConfig.hpp"
|
||||
|
||||
#include <exception>
|
||||
|
||||
#include <wx/aboutdlg.h>
|
||||
#include <wx/artprov.h>
|
||||
#include <wx/defs.h>
|
||||
#include <wx/filedlg.h>
|
||||
#include <wx/fswatcher.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/menu.h>
|
||||
#include <wx/msgdlg.h>
|
||||
#include <wx/stringimpl.h>
|
||||
|
||||
cMainFrame::cMainFrame()
|
||||
: wxFrame(NULL, wxID_ANY, "SampleHive", wxDefaultPosition)
|
||||
{
|
||||
// Initialize statusbar with 4 sections
|
||||
m_pStatusBar = CreateStatusBar(4);
|
||||
|
||||
// Set width for each section of the statusbar
|
||||
int status_width[4] = { 300, -6, -1, -2 };
|
||||
m_pStatusBar->SetStatusWidths(4, status_width);
|
||||
|
||||
m_pHiveBitmap = new wxStaticBitmap(m_pStatusBar, wxID_ANY, wxBitmap(ICON_HIVE_24px, wxBITMAP_TYPE_PNG));
|
||||
|
||||
// Initialize menubar and menus
|
||||
m_pMenuBar = new wxMenuBar();
|
||||
m_pFileMenu = new wxMenu();
|
||||
m_pEditMenu = new wxMenu();
|
||||
m_pViewMenu = new wxMenu();
|
||||
m_pHelpMenu = new wxMenu();
|
||||
|
||||
// File menu items
|
||||
m_pAddFile = new wxMenuItem(m_pFileMenu, SampleHive::ID::MN_AddFile, _("Add a file\tCtrl+F"), _("Add a file"));
|
||||
m_pAddFile->SetBitmap(wxArtProvider::GetBitmap(wxART_NORMAL_FILE));
|
||||
m_pFileMenu->Append(m_pAddFile);
|
||||
|
||||
m_pAddDirectory = new wxMenuItem(m_pFileMenu, SampleHive::ID::MN_AddDirectory, _("Add a directory\tCtrl+D"), _("Add a directory"));
|
||||
m_pAddDirectory->SetBitmap(wxArtProvider::GetBitmap(wxART_FOLDER));
|
||||
m_pFileMenu->Append(m_pAddDirectory);
|
||||
|
||||
m_pFileMenu->AppendSeparator();
|
||||
|
||||
m_pFileMenu->Append(wxID_EXIT, wxEmptyString, _("Exits the application"));
|
||||
|
||||
// Edit menu items
|
||||
m_pEditMenu->Append(wxID_PREFERENCES, _("Preferences\tCtrl+P"), _("Open preferences dialog"));
|
||||
|
||||
// View menu items
|
||||
m_pDemoMode = new wxMenuItem(m_pViewMenu, wxID_ANY, _("Demo mode"), _("Toggle demo mode On/Off"), wxITEM_CHECK);
|
||||
m_pToggleExtension = new wxMenuItem(m_pViewMenu, SampleHive::ID::MN_ToggleExtension,
|
||||
_("Toggle Extension\tCtrl+E"), _("Show/Hide Extension"), wxITEM_CHECK);
|
||||
m_pToggleMenuBar = new wxMenuItem(m_pViewMenu, SampleHive::ID::MN_ToggleMenuBar,
|
||||
_("Toggle Menu Bar\tCtrl+M"), _("Show/Hide Menu Bar"), wxITEM_CHECK);
|
||||
m_pToggleStatusBar = new wxMenuItem(m_pViewMenu, SampleHive::ID::MN_ToggleStatusBar,
|
||||
_("Toggle Status Bar\tCtrl+B"), _("Show/Hide Status Bar"), wxITEM_CHECK);
|
||||
|
||||
m_pViewMenu->Append(m_pDemoMode)->Check(false);
|
||||
m_pViewMenu->Append(m_pToggleExtension)->Check(true);
|
||||
m_pViewMenu->Append(m_pToggleMenuBar)->Check(m_pMenuBar->IsShown());
|
||||
m_pViewMenu->Append(m_pToggleStatusBar)->Check(m_pStatusBar->IsShown());
|
||||
|
||||
// Help menu items
|
||||
m_pHelpMenu->Append(wxID_REFRESH, _("Reset app data"), _("Clear the application data revert to default configuration"));
|
||||
m_pHelpMenu->Append(wxID_ABOUT, wxEmptyString, _("Show about the application"));
|
||||
|
||||
// Append all menus to menubar
|
||||
m_pMenuBar->Append(m_pFileMenu, _("&File"));
|
||||
m_pMenuBar->Append(m_pEditMenu, _("&Edit"));
|
||||
m_pMenuBar->Append(m_pViewMenu, _("&View"));
|
||||
m_pMenuBar->Append(m_pHelpMenu, _("&Help"));
|
||||
|
||||
// Set the menu bar to use
|
||||
SetMenuBar(m_pMenuBar);
|
||||
|
||||
// Load default yaml config file.
|
||||
LoadConfigFile();
|
||||
|
||||
// Initialize the database
|
||||
InitDatabase();
|
||||
|
||||
// Initializing Sizers
|
||||
m_pMainSizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_pTopPanelMainSizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
// Creating top splitter window
|
||||
m_pTopSplitter = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
|
||||
wxSP_NOBORDER | wxSP_LIVE_UPDATE | wxSP_THIN_SASH);
|
||||
m_pTopSplitter->SetMinimumPaneSize(200);
|
||||
m_pTopSplitter->SetSashGravity(0);
|
||||
|
||||
// Top half of TopSplitter window
|
||||
m_pTopPanel = new wxPanel(m_pTopSplitter, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
|
||||
|
||||
// Bottom half of the TopSplitter window
|
||||
m_pBottomSplitter = new wxSplitterWindow(m_pTopSplitter, wxID_ANY, wxDefaultPosition, wxDefaultSize,
|
||||
wxSP_NOBORDER | wxSP_LIVE_UPDATE | wxSP_THIN_SASH);
|
||||
m_pBottomSplitter->SetMinimumPaneSize(300);
|
||||
m_pBottomSplitter->SetSashGravity(0);
|
||||
|
||||
m_pNotebook = new cNotebook(m_pBottomSplitter);
|
||||
|
||||
m_pLibrary = new cLibrary(m_pBottomSplitter);
|
||||
|
||||
if (m_bDemoMode)
|
||||
{
|
||||
m_pLibrary->GetInfoBarObject()->ShowMessage("WARNING: Demo mode is turned on, all samples will be deleted on application exit.", wxICON_WARNING);
|
||||
}
|
||||
|
||||
SampleHive::cHiveData::Get().InitHiveData(*m_pLibrary->GetListCtrlObject(),
|
||||
*m_pNotebook->GetHivesPanel()->GetHivesObject(),
|
||||
m_pNotebook->GetHivesPanel()->GetFavoritesHive(),
|
||||
*m_pNotebook->GetTrashPanel()->GetTrashObject(),
|
||||
m_pNotebook->GetTrashPanel()->GetTrashRoot());
|
||||
|
||||
// Set split direction
|
||||
m_pTopSplitter->SplitHorizontally(m_pTopPanel, m_pBottomSplitter);
|
||||
m_pBottomSplitter->SplitVertically(m_pNotebook, m_pLibrary);
|
||||
|
||||
// Initializing wxMediaCtrl.
|
||||
m_pMediaCtrl = new wxMediaCtrl(this, SampleHive::ID::BC_MediaCtrl, wxEmptyString, wxDefaultPosition,
|
||||
wxDefaultSize, 0, wxEmptyString);
|
||||
|
||||
// Intializing wxTimer
|
||||
m_pTimer = new wxTimer(this);
|
||||
|
||||
m_pTransportControls = new cTransportControls(m_pTopPanel, *m_pMediaCtrl);
|
||||
m_pWaveformViewer = new cWaveformViewer(m_pTopPanel, *m_pMediaCtrl);
|
||||
|
||||
// Binding events.
|
||||
Bind(wxEVT_MENU, &cMainFrame::OnSelectAddFile, this, SampleHive::ID::MN_AddFile);
|
||||
Bind(wxEVT_MENU, &cMainFrame::OnSelectAddDirectory, this, SampleHive::ID::MN_AddDirectory);
|
||||
Bind(wxEVT_MENU, &cMainFrame::OnSelectToggleDemoMode, this, m_pDemoMode->GetId());
|
||||
Bind(wxEVT_MENU, &cMainFrame::OnSelectToggleExtension, this, SampleHive::ID::MN_ToggleExtension);
|
||||
Bind(wxEVT_MENU, &cMainFrame::OnSelectToggleMenuBar, this, SampleHive::ID::MN_ToggleMenuBar);
|
||||
Bind(wxEVT_MENU, &cMainFrame::OnSelectToggleStatusBar, this, SampleHive::ID::MN_ToggleStatusBar);
|
||||
Bind(wxEVT_MENU, &cMainFrame::OnSelectExit, this, wxID_EXIT);
|
||||
Bind(wxEVT_MENU, &cMainFrame::OnSelectPreferences, this, wxID_PREFERENCES);
|
||||
Bind(wxEVT_MENU, &cMainFrame::OnSelectResetAppData, this, wxID_REFRESH);
|
||||
Bind(wxEVT_MENU, &cMainFrame::OnSelectAbout, this, wxID_ABOUT);
|
||||
|
||||
Bind(wxEVT_SPLITTER_SASH_POS_CHANGING, &cMainFrame::OnTopSplitterSashPosChanged, this, m_pTopSplitter->GetId());
|
||||
Bind(wxEVT_SPLITTER_SASH_POS_CHANGING, &cMainFrame::OnBottomSplitterSashPosChanged, this, m_pBottomSplitter->GetId());
|
||||
|
||||
this->Connect(wxEVT_SIZE, wxSizeEventHandler(cMainFrame::OnResizeFrame), NULL, this);
|
||||
m_pStatusBar->Connect(wxEVT_SIZE, wxSizeEventHandler(cMainFrame::OnResizeStatusBar), NULL, this);
|
||||
|
||||
Bind(wxEVT_MEDIA_FINISHED, &cMainFrame::OnMediaFinished, this, SampleHive::ID::BC_MediaCtrl);
|
||||
|
||||
Bind(wxEVT_TIMER, &cMainFrame::UpdateElapsedTime, this);
|
||||
|
||||
Bind(SampleHive::SH_EVT_LOOP_POINTS_UPDATED, &cMainFrame::OnRecieveLoopPoints, this);
|
||||
Bind(SampleHive::SH_EVT_LOOP_POINTS_CLEAR, &cMainFrame::OnRecieveClearLoopPointsStatus, this);
|
||||
Bind(SampleHive::SH_EVT_STATUSBAR_STATUS_PUSH, &cMainFrame::OnRecievePushStatusBarStatus, this);
|
||||
Bind(SampleHive::SH_EVT_STATUSBAR_STATUS_POP, &cMainFrame::OnRecievePopStatusBarStatus, this);
|
||||
Bind(SampleHive::SH_EVT_STATUSBAR_STATUS_SET, &cMainFrame::OnRecieveSetStatusBarStatus, this);
|
||||
Bind(SampleHive::SH_EVT_INFOBAR_MESSAGE_SHOW, &cMainFrame::OnRecieveInfoBarStatus, this);
|
||||
Bind(SampleHive::SH_EVT_TIMER_STOP, &cMainFrame::OnRecieveTimerStopStatus, this);
|
||||
Bind(SampleHive::SH_EVT_UPDATE_WAVEFORM, &cMainFrame::OnRecieveWaveformUpdateStatus, this);
|
||||
Bind(SampleHive::SH_EVT_CALL_FUNC_PLAY, &cMainFrame::OnRecieveCallFunctionPlay, this);
|
||||
Bind(SampleHive::SH_EVT_LOOP_AB_BUTTON_VALUE_CHANGE, &cMainFrame::OnRecieveLoopABButtonValueChange, this);
|
||||
|
||||
// Adding widgets to their sizers
|
||||
m_pMainSizer->Add(m_pTopSplitter, 1, wxALL | wxEXPAND, 0);
|
||||
|
||||
m_pTopPanelMainSizer->Add(m_pWaveformViewer, 1, wxALL | wxEXPAND, 2);
|
||||
m_pTopPanelMainSizer->Add(m_pTransportControls, 0, wxALL | wxEXPAND, 2);
|
||||
|
||||
// Sizer for the frame
|
||||
this->SetSizer(m_pMainSizer);
|
||||
this->Layout();
|
||||
this->Center(wxBOTH);
|
||||
|
||||
// Sizer for TopPanel
|
||||
m_pTopPanel->SetSizer(m_pTopPanelMainSizer);
|
||||
m_pTopPanelMainSizer->Fit(m_pTopPanel);
|
||||
m_pTopPanelMainSizer->SetSizeHints(m_pTopPanel);
|
||||
m_pTopPanelMainSizer->Layout();
|
||||
|
||||
// Restore the data previously added to Library only if demo mode is disabled
|
||||
if (!m_bDemoMode)
|
||||
LoadDatabase();
|
||||
|
||||
// Set some properites after the frame has been created
|
||||
CallAfter(&cMainFrame::SetAfterFrameCreate);
|
||||
}
|
||||
|
||||
void cMainFrame::OnMediaFinished(wxMediaEvent& event)
|
||||
{
|
||||
if (m_pTransportControls->CanLoop())
|
||||
{
|
||||
// FIXME: Temporary fix for the sample not playing from beginning when looping. Might need to change this.
|
||||
if (m_pMediaCtrl->Stop()) // TODO: <--
|
||||
if (!m_pMediaCtrl->Play())
|
||||
{
|
||||
wxMessageDialog msgDialog(NULL, _("Error! Cannot loop media."), _("Error"), wxOK | wxICON_ERROR);
|
||||
msgDialog.ShowModal();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_pTimer->IsRunning())
|
||||
{
|
||||
m_pTimer->Stop();
|
||||
SH_LOG_DEBUG("Stopping timer.");
|
||||
}
|
||||
|
||||
m_pTransportControls->SetSamplePositionText("--:--.---/--:--.---");
|
||||
PopStatusText(1);
|
||||
this->SetStatusText(_("Stopped"), 1);
|
||||
}
|
||||
}
|
||||
|
||||
void cMainFrame::UpdateElapsedTime(wxTimerEvent& event)
|
||||
{
|
||||
wxString duration, position;
|
||||
|
||||
duration = SampleHive::cUtils::Get().CalculateAndGetISOStandardTime(m_pMediaCtrl->Length());
|
||||
position = SampleHive::cUtils::Get().CalculateAndGetISOStandardTime(m_pMediaCtrl->Tell());
|
||||
|
||||
m_pTransportControls->SetSamplePositionText(wxString::Format(wxT("%s/%s"), position.c_str(), duration.c_str()));
|
||||
|
||||
m_pWaveformViewer->Refresh();
|
||||
|
||||
if (m_bLoopPointsSet && m_pTransportControls->IsLoopABOn())
|
||||
if (static_cast<double>(m_pMediaCtrl->Tell()) >= m_LoopB.ToDouble())
|
||||
m_pMediaCtrl->Seek(m_LoopA.ToDouble(), wxFromStart);
|
||||
}
|
||||
|
||||
void cMainFrame::LoadDatabase()
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
try
|
||||
{
|
||||
const auto dataset = m_pDatabase->LoadSamplesDatabase(*m_pNotebook->GetHivesPanel()->GetHivesObject(),
|
||||
m_pNotebook->GetHivesPanel()->GetFavoritesHive(),
|
||||
*m_pNotebook->GetTrashPanel()->GetTrashObject(),
|
||||
m_pNotebook->GetTrashPanel()->GetTrashRoot(),
|
||||
serializer.DeserializeShowFileExtension(),
|
||||
ICON_STAR_FILLED_16px, ICON_STAR_EMPTY_16px);
|
||||
|
||||
if (dataset.empty())
|
||||
SH_LOG_INFO("Error! Database is empty.");
|
||||
else
|
||||
{
|
||||
for (auto data : dataset)
|
||||
SampleHive::cHiveData::Get().ListCtrlAppendItem(data);
|
||||
}
|
||||
|
||||
m_pDatabase->LoadHivesDatabase(*m_pNotebook->GetHivesPanel()->GetHivesObject());
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
SH_LOG_ERROR("Error loading data. {}", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
void cMainFrame::LoadConfigFile()
|
||||
{
|
||||
// Check if SampleHive configuration directory exist and create it if not
|
||||
if (!wxDirExists(APP_CONFIG_DIR))
|
||||
{
|
||||
SH_LOG_WARN("Configuration directory not found. Creating directory at {}", static_cast<std::string>(APP_CONFIG_DIR));
|
||||
|
||||
if (wxFileName::Mkdir(APP_CONFIG_DIR, wxPOSIX_USER_READ | wxPOSIX_USER_WRITE | wxPOSIX_USER_EXECUTE |
|
||||
wxPOSIX_GROUP_READ | wxPOSIX_GROUP_EXECUTE |
|
||||
wxPOSIX_OTHERS_READ | wxPOSIX_OTHERS_EXECUTE, wxPATH_MKDIR_FULL))
|
||||
{
|
||||
SH_LOG_INFO("Successfully created configuration directory at {}", static_cast<std::string>(APP_CONFIG_DIR));
|
||||
}
|
||||
else
|
||||
{
|
||||
wxMessageBox(wxString::Format(_("Error! Could not create configuration directory %s"), APP_CONFIG_DIR),
|
||||
_("Error!"), wxOK | wxCENTRE, this);
|
||||
}
|
||||
}
|
||||
else
|
||||
SH_LOG_INFO("Found {} directory.", static_cast<std::string>(APP_CONFIG_DIR));
|
||||
|
||||
// Check if SampleHive data directory exist and create it if not
|
||||
if (!wxDirExists(APP_DATA_DIR))
|
||||
{
|
||||
SH_LOG_WARN("Data directory not found. Creating directory at {}", static_cast<std::string>(APP_DATA_DIR));
|
||||
|
||||
if (wxFileName::Mkdir(APP_DATA_DIR, wxPOSIX_USER_READ | wxPOSIX_USER_WRITE | wxPOSIX_USER_EXECUTE |
|
||||
wxPOSIX_GROUP_READ | wxPOSIX_GROUP_EXECUTE |
|
||||
wxPOSIX_OTHERS_READ | wxPOSIX_OTHERS_EXECUTE, wxPATH_MKDIR_FULL))
|
||||
{
|
||||
SH_LOG_INFO("Successfully created data directory at {}", static_cast<std::string>(APP_DATA_DIR));
|
||||
}
|
||||
else
|
||||
{
|
||||
wxMessageBox(wxString::Format(_("Error! Could not create data directory %s"), APP_DATA_DIR),
|
||||
_("Error!"), wxOK | wxCENTRE, this);
|
||||
}
|
||||
}
|
||||
else
|
||||
SH_LOG_INFO("Found {} directory.", static_cast<std::string>(APP_DATA_DIR));
|
||||
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
SH_LOG_INFO("Reading configuration file..");
|
||||
|
||||
int height = 600, width = 800;
|
||||
|
||||
width = serializer.DeserializeWinSize().first;
|
||||
height = serializer.DeserializeWinSize().second;
|
||||
|
||||
int min_width = 960, min_height = 540;
|
||||
|
||||
m_bShowMenuBar = serializer.DeserializeShowMenuAndStatusBar("menubar");
|
||||
m_bShowStatusBar = serializer.DeserializeShowMenuAndStatusBar("statusbar");
|
||||
m_bDemoMode = serializer.DeserializeDemoMode();
|
||||
|
||||
m_pToggleMenuBar->Check(m_bShowMenuBar);
|
||||
m_pMenuBar->Show(m_bShowMenuBar);
|
||||
m_pToggleStatusBar->Check(m_bShowStatusBar);
|
||||
m_pStatusBar->Show(m_bShowStatusBar);
|
||||
m_pDemoMode->Check(m_bDemoMode);
|
||||
m_pToggleExtension->Check(serializer.DeserializeShowFileExtension());
|
||||
|
||||
this->SetFont(serializer.DeserializeFontSettings());
|
||||
this->SetSize(width, height);
|
||||
this->SetMinSize(wxSize(min_width, min_height));
|
||||
this->CenterOnScreen(wxBOTH);
|
||||
this->SetIcon(wxIcon(ICON_HIVE_256px, wxBITMAP_TYPE_PNG));
|
||||
this->SetTitle(PROJECT_NAME);
|
||||
this->SetStatusText(wxString::Format("%s %s", PROJECT_NAME, PROJECT_VERSION), 3);
|
||||
this->SetStatusText(_("Stopped"), 1);
|
||||
}
|
||||
|
||||
// void cMainFrame::RefreshDatabase()
|
||||
// {
|
||||
// m_pLibrary->GetListCtrlObject()->DeleteAllItems();
|
||||
|
||||
// if (m_pNotebook->GetHivesPanel()->GetHivesObject()->GetChildCount(wxDataViewItem(wxNullPtr)) <= 1 &&
|
||||
// m_pNotebook->GetHivesPanel()->GetHivesObject()->GetItemText(wxDataViewItem(wxNullPtr)) ==
|
||||
// m_pNotebook->GetHivesPanel()->GetHivesObject()->GetItemText(m_pNotebook->GetHivesPanel()->GetFavoritesHive()))
|
||||
// return;
|
||||
// else
|
||||
// m_pNotebook->GetHivesPanel()->GetHivesObject()->DeleteAllItems();
|
||||
|
||||
// m_pNotebook->GetTrashPanel()->GetTrashObject()->DeleteAllItems();
|
||||
|
||||
// LoadDatabase();
|
||||
// }
|
||||
|
||||
bool cMainFrame::CreateWatcherIfNecessary()
|
||||
{
|
||||
if (m_pFsWatcher)
|
||||
return false;
|
||||
|
||||
CreateWatcher();
|
||||
Bind(wxEVT_FSWATCHER, &cMainFrame::OnFileSystemEvent, this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void cMainFrame::CreateWatcher()
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
wxCHECK_RET(!m_pFsWatcher, _("Watcher already initialized"));
|
||||
|
||||
m_pFsWatcher = new wxFileSystemWatcher();
|
||||
m_pFsWatcher->SetOwner(this);
|
||||
|
||||
wxString path = serializer.DeserializeAutoImport().second;
|
||||
|
||||
if (serializer.DeserializeAutoImport().first)
|
||||
{
|
||||
SH_LOG_INFO("Adding watch entry: {}", path.ToStdString());
|
||||
|
||||
if (serializer.DeserializeRecursiveImport())
|
||||
AddWatchEntry(wxFSWPath_Tree, path.ToStdString());
|
||||
else
|
||||
AddWatchEntry(wxFSWPath_Dir, path.ToStdString());
|
||||
}
|
||||
}
|
||||
|
||||
void cMainFrame::AddWatchEntry(wxFSWPathType type, std::string path)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
if (path.empty())
|
||||
{
|
||||
path = wxDirSelector(_("Choose a directory to watch"), "", wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST);
|
||||
|
||||
if (path.empty())
|
||||
return;
|
||||
}
|
||||
|
||||
wxCHECK_RET(m_pFsWatcher, _("Watcher not initialized"));
|
||||
|
||||
SH_LOG_INFO("Adding {}: '{}'", path, type == wxFSWPath_Dir ? "directory" : "directory tree");
|
||||
|
||||
wxFileName filename = wxFileName::DirName(path);
|
||||
|
||||
if (!filename.IsOk() || !filename.IsDir() || !filename.IsDirReadable())
|
||||
{
|
||||
SH_LOG_ERROR("Error! Something wrong with {} path", filename.GetFullPath().ToStdString());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!serializer.DeserializeFollowSymLink())
|
||||
{
|
||||
filename.DontFollowLink();
|
||||
}
|
||||
|
||||
bool ok = false;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case wxFSWPath_Dir:
|
||||
ok = m_pFsWatcher->Add(filename);
|
||||
break;
|
||||
case wxFSWPath_Tree:
|
||||
ok = m_pFsWatcher->AddTree(filename);
|
||||
break;
|
||||
case wxFSWPath_File:
|
||||
break;
|
||||
case wxFSWPath_None:
|
||||
wxFAIL_MSG(_("Error! Unexpected path type."));
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
SH_LOG_ERROR("Error! Cannot add '{}' to watched paths", filename.GetPath().ToStdString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void cMainFrame::OnFileSystemEvent(wxFileSystemWatcherEvent& event)
|
||||
{
|
||||
wxLogTrace(wxTRACE_FSWATCHER, "*** %s ***", event.ToString());
|
||||
|
||||
int type = event.GetChangeType();
|
||||
|
||||
wxString path = event.GetPath().GetFullPath();
|
||||
|
||||
wxArrayString files;
|
||||
files.push_back(path);
|
||||
|
||||
SH_LOG_DEBUG("{} {}", path.ToStdString(), event.ToString().ToStdString());
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case wxFSW_EVENT_CREATE:
|
||||
SH_LOG_INFO("NEW FILES DETECTED, ADDING: {}", path.ToStdString());
|
||||
SampleHive::cUtils::Get().AddSamples(files, this);
|
||||
break;
|
||||
case wxFSW_EVENT_ACCESS:
|
||||
SH_LOG_INFO("ACCESSING DIRECTORY: {}", path.ToStdString());
|
||||
break;
|
||||
case wxFSW_EVENT_DELETE:
|
||||
SH_LOG_INFO("FILES DELETED IN DIRECTORY: {}", path.ToStdString());
|
||||
break;
|
||||
case wxFSW_EVENT_MODIFY:
|
||||
SH_LOG_INFO("DIRECTORY MODIFIED: {}", path.ToStdString());
|
||||
break;
|
||||
case wxFSW_EVENT_RENAME:
|
||||
SH_LOG_INFO("FILES RENAMED IN DIRECTORY: {}", event.GetNewPath().GetFullPath().ToStdString());
|
||||
break;
|
||||
case wxFSW_EVENT_WARNING:
|
||||
SH_LOG_INFO("Filesystem watcher warning: {}", static_cast<int>(event.GetWarningType()));
|
||||
break;
|
||||
case wxFSW_EVENT_ERROR:
|
||||
SH_LOG_INFO("Error! Filesystem watcher: {}", event.GetErrorDescription().ToStdString());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void cMainFrame::OnSelectAddFile(wxCommandEvent& event)
|
||||
{
|
||||
wxFileDialog file_dialog(this, wxFileSelectorPromptStr, USER_HOME_DIR,
|
||||
wxEmptyString, wxFileSelectorDefaultWildcardStr,
|
||||
wxFD_DEFAULT_STYLE | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE | wxFD_PREVIEW,
|
||||
wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
switch (file_dialog.ShowModal())
|
||||
{
|
||||
case wxID_OK:
|
||||
{
|
||||
wxArrayString paths;
|
||||
file_dialog.GetPaths(paths);
|
||||
|
||||
for (size_t i = 0; i < (size_t)paths.size(); i++)
|
||||
SampleHive::cUtils::Get().AddSamples(paths, this);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void cMainFrame::OnSelectAddDirectory(wxCommandEvent& event)
|
||||
{
|
||||
wxDirDialog dir_dialog(this, wxDirSelectorPromptStr, USER_HOME_DIR,
|
||||
wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST, wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
switch (dir_dialog.ShowModal())
|
||||
{
|
||||
case wxID_OK:
|
||||
{
|
||||
wxString path = dir_dialog.GetPath();
|
||||
|
||||
SampleHive::cUtils::Get().OnAutoImportDir(path, this);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void cMainFrame::OnSelectToggleDemoMode(wxCommandEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
if (m_pDemoMode->IsChecked())
|
||||
{
|
||||
serializer.SerializeDemoMode(true);
|
||||
m_pLibrary->GetInfoBarObject()->ShowMessage(_("Demo mode toggled on, "
|
||||
"please restart the app for changes take effect"), wxICON_INFORMATION);
|
||||
|
||||
m_bDemoMode = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
serializer.SerializeDemoMode(false);
|
||||
m_pLibrary->GetInfoBarObject()->ShowMessage(_("Demo mode toggled off, "
|
||||
"please restart the app for changes take effect"), wxICON_INFORMATION);
|
||||
|
||||
m_bDemoMode = false;
|
||||
}
|
||||
}
|
||||
|
||||
void cMainFrame::OnSelectToggleExtension(wxCommandEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
if (m_pToggleExtension->IsChecked())
|
||||
{
|
||||
serializer.SerializeShowFileExtension(true);
|
||||
m_pLibrary->GetInfoBarObject()->ShowMessage(_("Extension showing, restart the application to view changes "
|
||||
"or press CTRL+E to toggle show/hide."), wxICON_INFORMATION);
|
||||
}
|
||||
else
|
||||
{
|
||||
serializer.SerializeShowFileExtension(false);
|
||||
m_pLibrary->GetInfoBarObject()->ShowMessage(_("Extension hidden, restart the application to view changes "
|
||||
"or press CTRL+E to toggle show/hide."), wxICON_INFORMATION);
|
||||
}
|
||||
}
|
||||
|
||||
void cMainFrame::OnSelectToggleMenuBar(wxCommandEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
if (m_pToggleMenuBar->IsChecked())
|
||||
{
|
||||
m_pMenuBar->Show();
|
||||
m_pLibrary->GetInfoBarObject()->ShowMessage(_("MenuBar showing, press CTRL+M to toggle show/hide."), wxICON_INFORMATION);
|
||||
|
||||
m_bShowMenuBar = true;
|
||||
|
||||
serializer.SerializeShowMenuAndStatusBar("menubar", m_bShowMenuBar);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pMenuBar->Hide();
|
||||
m_pLibrary->GetInfoBarObject()->ShowMessage(_("MenuBar hidden, press CTRL+M to toggle show/hide."), wxICON_INFORMATION);
|
||||
|
||||
m_bShowMenuBar = false;
|
||||
|
||||
serializer.SerializeShowMenuAndStatusBar("menubar", m_bShowMenuBar);
|
||||
}
|
||||
}
|
||||
|
||||
void cMainFrame::OnSelectToggleStatusBar(wxCommandEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
if (m_pToggleStatusBar->IsChecked())
|
||||
{
|
||||
m_pStatusBar->Show();
|
||||
m_pLibrary->GetInfoBarObject()->ShowMessage(_("StatusBar showing, press CTRL+B to toggle show/hide."), wxICON_INFORMATION);
|
||||
|
||||
m_bShowStatusBar = true;
|
||||
|
||||
serializer.SerializeShowMenuAndStatusBar("statusbar", m_bShowStatusBar);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pStatusBar->Hide();
|
||||
m_pLibrary->GetInfoBarObject()->ShowMessage(_("StatusBar hidden, press CTRL+B to toggle show/hide."), wxICON_INFORMATION);
|
||||
|
||||
m_bShowStatusBar = false;
|
||||
|
||||
serializer.SerializeShowMenuAndStatusBar("statusbar", m_bShowStatusBar);
|
||||
}
|
||||
}
|
||||
|
||||
void cMainFrame::OnSelectExit(wxCommandEvent& event)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
void cMainFrame::OnSelectPreferences(wxCommandEvent& event)
|
||||
{
|
||||
cSettings* settings = new cSettings(this);
|
||||
|
||||
switch (settings->ShowModal())
|
||||
{
|
||||
case wxID_OK:
|
||||
if (settings->CanAutoImport())
|
||||
{
|
||||
SampleHive::cUtils::Get().OnAutoImportDir(settings->GetImportDirPath(), this);
|
||||
// RefreshDatabase();
|
||||
}
|
||||
if (settings->IsWaveformColourChanged())
|
||||
{
|
||||
m_pWaveformViewer->ResetBitmapDC();
|
||||
}
|
||||
break;
|
||||
case wxID_CANCEL:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void cMainFrame::OnSelectResetAppData(wxCommandEvent& event)
|
||||
{
|
||||
wxMessageDialog clearDataDialog(this, wxString::Format(_("Warning! This will delete configuration file "
|
||||
"\"%s\" and database file \"%s\" permanently, "
|
||||
"are you sure you want to delete these files?"),
|
||||
static_cast<std::string>(CONFIG_FILEPATH),
|
||||
static_cast<std::string>(DATABASE_FILEPATH)),
|
||||
_("Clear app data?"), wxYES_NO | wxNO_DEFAULT | wxCENTRE, wxDefaultPosition);
|
||||
|
||||
bool remove = false;
|
||||
|
||||
switch (clearDataDialog.ShowModal())
|
||||
{
|
||||
case wxID_YES:
|
||||
remove = true;
|
||||
|
||||
if (remove)
|
||||
{
|
||||
if (!wxFileExists(static_cast<std::string>(CONFIG_FILEPATH)))
|
||||
{
|
||||
SH_LOG_ERROR("Error! File {} doesn't exist.", static_cast<std::string>(CONFIG_FILEPATH));
|
||||
return;
|
||||
}
|
||||
|
||||
bool config_is_deleted = wxRemoveFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (config_is_deleted)
|
||||
SH_LOG_INFO("Deleted {}", static_cast<std::string>(CONFIG_FILEPATH));
|
||||
else
|
||||
SH_LOG_ERROR("Could not delete {}", static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (!wxFileExists(static_cast<std::string>(DATABASE_FILEPATH)))
|
||||
{
|
||||
SH_LOG_ERROR("Error! File {} doesn't exist.", static_cast<std::string>(DATABASE_FILEPATH));
|
||||
return;
|
||||
}
|
||||
|
||||
bool db_is_deleted = wxRemoveFile(static_cast<std::string>(DATABASE_FILEPATH));
|
||||
|
||||
if (db_is_deleted)
|
||||
SH_LOG_INFO("Deleted {}", static_cast<std::string>(DATABASE_FILEPATH));
|
||||
else
|
||||
SH_LOG_ERROR("Could not delete {}", static_cast<std::string>(DATABASE_FILEPATH));
|
||||
|
||||
if (config_is_deleted && db_is_deleted)
|
||||
{
|
||||
m_pLibrary->GetInfoBarObject()->ShowMessage(_("Successfully cleared app data"), wxICON_INFORMATION);
|
||||
SH_LOG_INFO("Cleared app data successfully");
|
||||
}
|
||||
else
|
||||
wxMessageBox(_("Error! Could not clear app data"), _("Error!"), wxOK | wxCENTRE | wxICON_ERROR, this);
|
||||
}
|
||||
break;
|
||||
case wxID_NO:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void cMainFrame::OnSelectAbout(wxCommandEvent& event)
|
||||
{
|
||||
wxAboutDialogInfo aboutInfo;
|
||||
|
||||
aboutInfo.SetName(PROJECT_NAME);
|
||||
aboutInfo.SetIcon(wxIcon(ICON_HIVE_64px, wxBITMAP_TYPE_PNG));
|
||||
aboutInfo.AddArtist(PROJECT_AUTHOR);
|
||||
aboutInfo.SetVersion(PROJECT_VERSION, _("Version 0.9.0_alpha.1"));
|
||||
aboutInfo.SetDescription(_(PROJECT_DESCRIPTION));
|
||||
aboutInfo.SetCopyright("(C)" PROJECT_COPYRIGHT_YEARS);
|
||||
aboutInfo.SetWebSite(PROJECT_WEBSITE);
|
||||
aboutInfo.AddDeveloper(PROJECT_AUTHOR);
|
||||
aboutInfo.SetLicence(wxString::Format(wxString::FromAscii(
|
||||
"%s %s\n"
|
||||
"Copyright (C) %s Apoorv Singh\n"
|
||||
"\n"
|
||||
"%s is free software: you can redistribute it and/or modify\n"
|
||||
"it under the terms of the GNU General Public License as published by\n"
|
||||
"the Free Software Foundation, either version 3 of the License, or\n"
|
||||
"(at your option) any later version.\n"
|
||||
"\n"
|
||||
"%s is distributed in the hope that it will be useful,\n"
|
||||
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||||
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
||||
"GNU General Public License for more details.\n"
|
||||
"\n"
|
||||
"You should have received a copy of the GNU General Public License\n"
|
||||
"along with this program. If not, see <https://www.gnu.org/licenses/>.\n"
|
||||
), PROJECT_NAME, PROJECT_VERSION, PROJECT_COPYRIGHT_YEARS, PROJECT_NAME, PROJECT_NAME));
|
||||
|
||||
wxAboutBox(aboutInfo);
|
||||
}
|
||||
|
||||
void cMainFrame::OnResizeStatusBar(wxSizeEvent& event)
|
||||
{
|
||||
wxRect rect;
|
||||
m_pStatusBar->GetFieldRect(2, rect);
|
||||
|
||||
wxSize bitmap_size = m_pHiveBitmap->GetSize();
|
||||
|
||||
m_pHiveBitmap->Move(rect.x + (rect.width - bitmap_size.x),
|
||||
rect.y + (rect.height - bitmap_size.y));
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void cMainFrame::OnResizeFrame(wxSizeEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
SH_LOG_DEBUG("Frame resized to {}, {}", GetSize().GetWidth(), GetSize().GetHeight());
|
||||
|
||||
serializer.SerializeWinSize(GetSize().GetWidth(), GetSize().GetHeight());
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void cMainFrame::OnTopSplitterSashPosChanged(wxSplitterEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
SH_LOG_DEBUG("TopSplitter at {}", m_pTopSplitter->GetSashPosition());
|
||||
|
||||
serializer.SerializeSplitterSashPos("top", m_pTopSplitter->GetSashPosition());
|
||||
}
|
||||
|
||||
void cMainFrame::OnBottomSplitterSashPosChanged(wxSplitterEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
SH_LOG_DEBUG("BottomSplitter at {}", m_pBottomSplitter->GetSashPosition());
|
||||
|
||||
serializer.SerializeSplitterSashPos("bottom", m_pBottomSplitter->GetSashPosition());
|
||||
}
|
||||
|
||||
void cMainFrame::SetAfterFrameCreate()
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
m_pTopSplitter->SetSashPosition(serializer.DeserializeSplitterSashPos("top"));
|
||||
m_pBottomSplitter->SetSashPosition(serializer.DeserializeSplitterSashPos("bottom"));
|
||||
}
|
||||
|
||||
void cMainFrame::OnRecieveLoopPoints(SampleHive::cLoopPointsEvent& event)
|
||||
{
|
||||
std::pair<double, double> loop_points = event.GetLoopPoints();
|
||||
|
||||
m_LoopA = wxLongLong(loop_points.first);
|
||||
m_LoopB = wxLongLong(loop_points.second);
|
||||
|
||||
int loopA_min = static_cast<int>((m_LoopA / 60000).GetValue());
|
||||
int loopA_sec = static_cast<int>(((m_LoopA % 60000) / 1000).GetValue());
|
||||
int loopB_min = static_cast<int>((m_LoopB / 60000).GetValue());
|
||||
int loopB_sec = static_cast<int>(((m_LoopB % 60000) / 1000).GetValue());
|
||||
|
||||
SH_LOG_INFO("Loop points set: A: {:2}:{:02}, B: {:2}:{:02}", loopA_min, loopA_sec, loopB_min, loopB_sec);
|
||||
|
||||
m_pTransportControls->SetLoopABValue(true);
|
||||
|
||||
m_bLoopPointsSet = true;
|
||||
}
|
||||
|
||||
void cMainFrame::OnRecievePushStatusBarStatus(SampleHive::cStatusBarStatusEvent& event)
|
||||
{
|
||||
std::pair<wxString, int> status = event.GetPushMessageAndSection();
|
||||
|
||||
m_pStatusBar->PushStatusText(status.first, status.second);
|
||||
}
|
||||
|
||||
void cMainFrame::OnRecievePopStatusBarStatus(SampleHive::cStatusBarStatusEvent& event)
|
||||
{
|
||||
m_pStatusBar->PopStatusText(event.GetPopMessageSection());
|
||||
}
|
||||
|
||||
void cMainFrame::OnRecieveSetStatusBarStatus(SampleHive::cStatusBarStatusEvent& event)
|
||||
{
|
||||
std::pair<wxString, int> status = event.GetStatusTextAndSection();
|
||||
|
||||
m_pStatusBar->SetStatusText(status.first, status.second);
|
||||
}
|
||||
|
||||
void cMainFrame::OnRecieveInfoBarStatus(SampleHive::cInfoBarMessageEvent& event)
|
||||
{
|
||||
std::pair<wxString, int> info = event.GetInfoBarMessage();
|
||||
|
||||
m_pLibrary->GetInfoBarObject()->ShowMessage(info.first, info.second);
|
||||
}
|
||||
|
||||
void cMainFrame::OnRecieveTimerStopStatus(SampleHive::cTimerEvent& event)
|
||||
{
|
||||
if (m_pTimer->IsRunning())
|
||||
m_pTimer->Stop();
|
||||
}
|
||||
|
||||
void cMainFrame::OnRecieveCallFunctionPlay(SampleHive::cCallFunctionEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
wxString selection = event.GetSlection();
|
||||
bool checkAutoplay = event.GetAutoplayValue();
|
||||
|
||||
wxString sample_path = SampleHive::cUtils::Get().GetFilenamePathAndExtension(selection).Path;
|
||||
|
||||
if (checkAutoplay)
|
||||
{
|
||||
if (m_pTransportControls->CanAutoplay())
|
||||
{
|
||||
if (m_bLoopPointsSet && m_pTransportControls->IsLoopABOn())
|
||||
PlaySample(sample_path.ToStdString(), selection.ToStdString(), true, m_LoopA.ToDouble(), wxFromStart);
|
||||
else
|
||||
PlaySample(sample_path.ToStdString(), selection.ToStdString());
|
||||
}
|
||||
else
|
||||
m_pMediaCtrl->Stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_bLoopPointsSet && m_pTransportControls->IsLoopABOn())
|
||||
PlaySample(sample_path.ToStdString(), selection.ToStdString(), true, m_LoopA.ToDouble(), wxFromStart);
|
||||
else
|
||||
PlaySample(sample_path.ToStdString(), selection.ToStdString());
|
||||
}
|
||||
}
|
||||
|
||||
void cMainFrame::OnRecieveWaveformUpdateStatus(SampleHive::cWaveformUpdateEvent& event)
|
||||
{
|
||||
m_pWaveformViewer->ResetBitmapDC();
|
||||
}
|
||||
|
||||
void cMainFrame::OnRecieveClearLoopPointsStatus(SampleHive::cLoopPointsEvent& event)
|
||||
{
|
||||
ClearLoopPoints();
|
||||
}
|
||||
|
||||
void cMainFrame::OnRecieveLoopABButtonValueChange(SampleHive::cLoopPointsEvent& event)
|
||||
{
|
||||
m_pTransportControls->SetLoopABValue(false);
|
||||
}
|
||||
|
||||
void cMainFrame::ClearLoopPoints()
|
||||
{
|
||||
m_LoopA = 0;
|
||||
m_LoopB = 0;
|
||||
|
||||
m_bLoopPointsSet = false;
|
||||
}
|
||||
|
||||
void cMainFrame::PlaySample(const std::string& filepath, const std::string& sample, bool seek, wxFileOffset where, wxSeekMode mode)
|
||||
{
|
||||
if (m_pMediaCtrl->Load(filepath))
|
||||
{
|
||||
if (seek)
|
||||
m_pMediaCtrl->Seek(where, mode);
|
||||
|
||||
if (!m_pMediaCtrl->Play())
|
||||
SH_LOG_ERROR("Error! Cannot play sample.");
|
||||
|
||||
// ====================================================
|
||||
// TODO: Remove these lines (for debugging only)
|
||||
float bpm = SampleHive::cUtils::Get().GetBPM(filepath);
|
||||
wxString bpm_str = SampleHive::cUtils::Get().GetBPMString(bpm);
|
||||
SH_LOG_DEBUG("BPM: {}, BPM_STR: {}", bpm, bpm_str.ToStdString());
|
||||
// ====================================================
|
||||
|
||||
PushStatusText(wxString::Format(_("Now playing: %s"), sample), 1);
|
||||
|
||||
if (!m_pTimer->IsRunning())
|
||||
{
|
||||
SH_LOG_DEBUG("Starting timer.");
|
||||
m_pTimer->Start(20, wxTIMER_CONTINUOUS);
|
||||
}
|
||||
}
|
||||
else
|
||||
SH_LOG_ERROR("Error! Cannot load sample.");
|
||||
}
|
||||
|
||||
void cMainFrame::InitDatabase()
|
||||
{
|
||||
// Initialize the database
|
||||
try
|
||||
{
|
||||
m_pDatabase = std::make_unique<cDatabase>();
|
||||
m_pDatabase->CreateTableSamples();
|
||||
|
||||
if (!m_bDemoMode)
|
||||
m_pDatabase->CreateTableHives();
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
SH_LOG_ERROR("Error! Cannot initialize database {}", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
cMainFrame::~cMainFrame()
|
||||
{
|
||||
// Delete wxTimer
|
||||
delete m_pTimer;
|
||||
|
||||
// Delete wxFilesystemWatcher
|
||||
delete m_pFsWatcher;
|
||||
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
if (serializer.DeserializeDemoMode())
|
||||
{
|
||||
if (wxFileExists("tempdb.db"))
|
||||
if (wxRemoveFile("tempdb.db"))
|
||||
SH_LOG_WARN("Deleted temporary database file..");
|
||||
else
|
||||
SH_LOG_ERROR("Could not delete file..");
|
||||
else
|
||||
SH_LOG_DEBUG("File doesn't exists");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,204 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GUI/Library.hpp"
|
||||
#include "GUI/Notebook.hpp"
|
||||
#include "GUI/TransportControls.hpp"
|
||||
#include "GUI/WaveformViewer.hpp"
|
||||
#include "Database/Database.hpp"
|
||||
#include "Utility/Serialize.hpp"
|
||||
#include "Utility/Event.hpp"
|
||||
#include "SampleHiveConfig.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <wx/event.h>
|
||||
#include <wx/frame.h>
|
||||
#include <wx/fswatcher.h>
|
||||
#include <wx/mediactrl.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/splitter.h>
|
||||
#include <wx/statbmp.h>
|
||||
#include <wx/statusbr.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/timer.h>
|
||||
|
||||
class cMainFrame : public wxFrame
|
||||
{
|
||||
public:
|
||||
cMainFrame();
|
||||
~cMainFrame();
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
// Top panel control handlers
|
||||
void OnMediaFinished(wxMediaEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// App menu items event handlers
|
||||
void OnSelectAddFile(wxCommandEvent& event);
|
||||
void OnSelectAddDirectory(wxCommandEvent& event);
|
||||
void OnSelectToggleDemoMode(wxCommandEvent& event);
|
||||
void OnSelectToggleExtension(wxCommandEvent& event);
|
||||
void OnSelectToggleMenuBar(wxCommandEvent& event);
|
||||
void OnSelectToggleStatusBar(wxCommandEvent& event);
|
||||
void OnSelectExit(wxCommandEvent& event);
|
||||
void OnSelectPreferences(wxCommandEvent& event);
|
||||
void OnSelectResetAppData(wxCommandEvent& event);
|
||||
void OnSelectAbout(wxCommandEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Statusbar event handler
|
||||
void OnResizeStatusBar(wxSizeEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Frame resize event handler
|
||||
void OnResizeFrame(wxSizeEvent& event);
|
||||
|
||||
// Splitter window sash pos event handler
|
||||
void OnTopSplitterSashPosChanged(wxSplitterEvent& event);
|
||||
void OnBottomSplitterSashPosChanged(wxSplitterEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Timer update event handler
|
||||
void UpdateElapsedTime(wxTimerEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void PlaySample(const std::string& filepath, const std::string& sample, bool seek = false,
|
||||
wxFileOffset where = NULL, wxSeekMode mode = wxFromStart);
|
||||
|
||||
// Recieve custom events
|
||||
// -------------------------------------------------------------------
|
||||
void OnRecieveLoopPoints(SampleHive::cLoopPointsEvent& event);
|
||||
void OnRecieveClearLoopPointsStatus(SampleHive::cLoopPointsEvent& event);
|
||||
void OnRecieveLoopABButtonValueChange(SampleHive::cLoopPointsEvent& event);
|
||||
void OnRecievePushStatusBarStatus(SampleHive::cStatusBarStatusEvent& event);
|
||||
void OnRecievePopStatusBarStatus(SampleHive::cStatusBarStatusEvent& event);
|
||||
void OnRecieveSetStatusBarStatus(SampleHive::cStatusBarStatusEvent& event);
|
||||
void OnRecieveInfoBarStatus(SampleHive::cInfoBarMessageEvent& event);
|
||||
void OnRecieveTimerStopStatus(SampleHive::cTimerEvent& event);
|
||||
void OnRecieveCallFunctionPlay(SampleHive::cCallFunctionEvent& event);
|
||||
void OnRecieveWaveformUpdateStatus(SampleHive::cWaveformUpdateEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void LoadDatabase();
|
||||
void LoadConfigFile();
|
||||
// void RefreshDatabase();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Directory watchers
|
||||
bool CreateWatcherIfNecessary();
|
||||
void CreateWatcher();
|
||||
void AddWatchEntry(wxFSWPathType type, std::string path);
|
||||
void OnFileSystemEvent(wxFileSystemWatcherEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Call after frame creation
|
||||
void SetAfterFrameCreate();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void ClearLoopPoints();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void InitDatabase();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
friend class cApp;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
// Main Panel
|
||||
wxBoxSizer* m_pMainSizer = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Hive bitmap icon for the statusbar
|
||||
wxStaticBitmap* m_pHiveBitmap = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// App statusbar
|
||||
wxStatusBar* m_pStatusBar = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// App menubar
|
||||
wxMenuBar* m_pMenuBar = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Menu and menu items for the menubar
|
||||
wxMenu* m_pFileMenu = nullptr;
|
||||
wxMenu* m_pEditMenu = nullptr;
|
||||
wxMenu* m_pViewMenu = nullptr;
|
||||
wxMenu* m_pHelpMenu = nullptr;
|
||||
wxMenuItem* m_pAddFile = nullptr;
|
||||
wxMenuItem* m_pAddDirectory = nullptr;
|
||||
wxMenuItem* m_pToggleExtension = nullptr;
|
||||
wxMenuItem* m_pToggleMenuBar = nullptr;
|
||||
wxMenuItem* m_pToggleStatusBar = nullptr;
|
||||
wxMenuItem* m_pDemoMode = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Splitter windows
|
||||
wxSplitterWindow* m_pTopSplitter = nullptr;
|
||||
wxSplitterWindow* m_pBottomSplitter = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Top panel controls
|
||||
wxPanel* m_pTopPanel = nullptr;
|
||||
cWaveformViewer* m_pWaveformViewer = nullptr;
|
||||
cTransportControls* m_pTransportControls = nullptr;
|
||||
wxBoxSizer* m_pTopPanelMainSizer = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Left panel controls
|
||||
cNotebook* m_pNotebook = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Right panel controls
|
||||
cLibrary* m_pLibrary = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// MediaCtrl
|
||||
wxMediaCtrl* m_pMediaCtrl = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Timer
|
||||
wxTimer* m_pTimer = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
std::unique_ptr<cDatabase> m_pDatabase = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// FileSystemWatcher
|
||||
wxFileSystemWatcher* m_pFsWatcher = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
wxLongLong m_LoopA, m_LoopB;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
bool m_bFiltered = false;
|
||||
bool m_bShowMenuBar = false;
|
||||
bool m_bShowStatusBar = false;
|
||||
bool m_bLoopPointsSet = false;
|
||||
bool m_bDemoMode = false;
|
||||
};
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "GUI/Notebook.hpp"
|
||||
#include "GUI/DirectoryBrowser.hpp"
|
||||
#include "GUI/Hives.hpp"
|
||||
#include "GUI/Trash.hpp"
|
||||
|
||||
cNotebook::cNotebook(wxWindow* window)
|
||||
: wxPanel(window, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL)
|
||||
{
|
||||
m_pNotebook = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP);
|
||||
|
||||
m_DirectoryBrowser = new cDirectoryBrowser(m_pNotebook);
|
||||
m_HivesPanel = new cHivesPanel(m_pNotebook);
|
||||
m_TrashPanel = new cTrashPanel(m_pNotebook);
|
||||
|
||||
// Adding the pages to wxNotebook
|
||||
m_pNotebook->AddPage(m_DirectoryBrowser, _("Browse"), false);
|
||||
m_pNotebook->AddPage(m_HivesPanel, _("Hives"), false);
|
||||
m_pNotebook->AddPage(m_TrashPanel, _("Trash"), false);
|
||||
|
||||
m_pSizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
m_pSizer->Add(m_pNotebook, wxSizerFlags(1).Expand());
|
||||
|
||||
this->SetSizer(m_pSizer);
|
||||
m_pSizer->Fit(this);
|
||||
m_pSizer->SetSizeHints(this);
|
||||
m_pSizer->Layout();
|
||||
}
|
||||
|
||||
cNotebook::~cNotebook()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GUI/DirectoryBrowser.hpp"
|
||||
#include "GUI/Hives.hpp"
|
||||
#include "GUI/Trash.hpp"
|
||||
|
||||
#include <wx/dataview.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/notebook.h>
|
||||
#include <wx/sizer.h>
|
||||
|
||||
class cNotebook : public wxPanel
|
||||
{
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
cNotebook(wxWindow* window);
|
||||
~cNotebook();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
cDirectoryBrowser* GetDirectoryBrowser() const { return m_DirectoryBrowser; }
|
||||
cHivesPanel* GetHivesPanel() const { return m_HivesPanel; }
|
||||
cTrashPanel* GetTrashPanel() const { return m_TrashPanel; }
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
wxNotebook* m_pNotebook = nullptr;
|
||||
wxBoxSizer* m_pSizer = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
cDirectoryBrowser* m_DirectoryBrowser = nullptr;
|
||||
cHivesPanel* m_HivesPanel = nullptr;
|
||||
cTrashPanel* m_TrashPanel = nullptr;
|
||||
};
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
#define wxUSE_RC_MANIFEST 1
|
||||
#define wxUSE_DPI_AWARE_MANIFEST 2
|
||||
|
||||
#include <wx/msw/wx.rc>
|
||||
|
||||
ApplicationIcon ICON "../../assets/icons/icon-hive_32x32.ico"
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "GUI/SearchBar.hpp"
|
||||
#include "GUI/ListCtrl.hpp"
|
||||
#include "Database/Database.hpp"
|
||||
#include "Utility/ControlIDs.hpp"
|
||||
#include "Utility/HiveData.hpp"
|
||||
#include "Utility/Serialize.hpp"
|
||||
#include "Utility/Paths.hpp"
|
||||
#include "Utility/Log.hpp"
|
||||
|
||||
#include <exception>
|
||||
|
||||
cSearchBar::cSearchBar(wxWindow* window)
|
||||
: wxSearchCtrl(window, SampleHive::ID::BC_Search, _("Search for samples.."),
|
||||
wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER),
|
||||
m_pWindow(window)
|
||||
{
|
||||
// Set minimum and maximum size of m_SearchBox
|
||||
// so it doesn't expand too wide when resizing the main frame.
|
||||
SetMinSize(wxSize(-1, 38));
|
||||
SetMaxSize(wxSize(-1, 38));
|
||||
|
||||
ShowSearchButton(true);
|
||||
ShowCancelButton(true);
|
||||
|
||||
Bind(wxEVT_TEXT, &cSearchBar::OnDoSearch, this, SampleHive::ID::BC_Search);
|
||||
Bind(wxEVT_SEARCHCTRL_SEARCH_BTN, &cSearchBar::OnDoSearch, this, SampleHive::ID::BC_Search);
|
||||
Bind(wxEVT_SEARCHCTRL_CANCEL_BTN, &cSearchBar::OnCancelSearch, this, SampleHive::ID::BC_Search);
|
||||
}
|
||||
|
||||
void cSearchBar::OnDoSearch(wxCommandEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
cDatabase db;
|
||||
|
||||
const auto search = this->GetValue().ToStdString();
|
||||
|
||||
try
|
||||
{
|
||||
const auto dataset = db.FilterDatabaseBySampleName(search, serializer.DeserializeShowFileExtension(),
|
||||
ICON_STAR_FILLED_16px, ICON_STAR_EMPTY_16px);
|
||||
|
||||
if (dataset.empty())
|
||||
{
|
||||
SH_LOG_INFO("Error! Database is empty.");
|
||||
}
|
||||
else
|
||||
{
|
||||
SampleHive::cHiveData::Get().ListCtrlDeleteAllItems();
|
||||
|
||||
std::cout << search << std::endl;
|
||||
|
||||
for (const auto& data : dataset)
|
||||
{
|
||||
SampleHive::cHiveData::Get().ListCtrlAppendItem(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
SH_LOG_ERROR("Error loading data. {}", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
void cSearchBar::OnCancelSearch(wxCommandEvent& event)
|
||||
{
|
||||
this->Clear();
|
||||
}
|
||||
|
||||
cSearchBar::~cSearchBar()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wx/dataview.h>
|
||||
#include <wx/srchctrl.h>
|
||||
|
||||
class cSearchBar : public wxSearchCtrl
|
||||
{
|
||||
public:
|
||||
cSearchBar(wxWindow* window);
|
||||
~cSearchBar();
|
||||
|
||||
public:
|
||||
wxSearchCtrl* GetSearchCtrlObject() { return this; }
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
// SearchCtrl event handlers
|
||||
void OnDoSearch(wxCommandEvent& event);
|
||||
void OnCancelSearch(wxCommandEvent& event);
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
wxWindow* m_pWindow = nullptr;
|
||||
};
|
||||
|
|
@ -0,0 +1,298 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "GUI/TransportControls.hpp"
|
||||
#include "GUI/Dialogs/Settings.hpp"
|
||||
#include "Utility/ControlIDs.hpp"
|
||||
#include "Utility/Event.hpp"
|
||||
#include "Utility/HiveData.hpp"
|
||||
#include "Utility/Sample.hpp"
|
||||
#include "Utility/Signal.hpp"
|
||||
#include "Utility/Serialize.hpp"
|
||||
#include "Utility/Log.hpp"
|
||||
#include "Utility/Paths.hpp"
|
||||
#include "Utility/Utils.hpp"
|
||||
|
||||
#include <wx/gdicmn.h>
|
||||
|
||||
cTransportControls::cTransportControls(wxWindow* window, wxMediaCtrl& mediaCtrl)
|
||||
: wxPanel(window, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL | wxNO_BORDER),
|
||||
m_MediaCtrl(mediaCtrl)
|
||||
{
|
||||
m_pMainSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
// Looping region controls
|
||||
if (m_Theme.IsDark())
|
||||
m_pLoopABButton = new wxBitmapToggleButton(this, SampleHive::ID::BC_LoopABButton,
|
||||
wxBitmap(ICON_AB_LIGHT_16px, wxBITMAP_TYPE_PNG),
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
else
|
||||
m_pLoopABButton = new wxBitmapToggleButton(this, SampleHive::ID::BC_LoopABButton,
|
||||
wxBitmap(ICON_AB_DARK_16px, wxBITMAP_TYPE_PNG),
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
|
||||
m_pLoopABButton->SetToolTip(_("Loop selected region"));
|
||||
|
||||
// Autoplay checkbox
|
||||
m_pAutoPlayCheck = new wxCheckBox(this, SampleHive::ID::BC_Autoplay, _("Autoplay"),
|
||||
wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
|
||||
m_pAutoPlayCheck->SetToolTip(_("Autoplay"));
|
||||
|
||||
// Volume slider
|
||||
m_pVolumeSlider = new wxSlider(this, SampleHive::ID::BC_Volume, 100, 0, 100, wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL);
|
||||
m_pVolumeSlider->SetToolTip(_("Volume"));
|
||||
m_pVolumeSlider->SetMinSize(wxSize(120, -1));
|
||||
m_pVolumeSlider->SetMaxSize(wxSize(120, -1));
|
||||
|
||||
// Sample position static text
|
||||
m_pSamplePosition = new wxStaticText(this, SampleHive::ID::BC_SamplePosition, "--:--.---/--:--.---",
|
||||
wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE_HORIZONTAL);
|
||||
|
||||
// Transport control buttons
|
||||
if (m_Theme.IsDark())
|
||||
{
|
||||
m_pPlayButton = new wxBitmapButton(this, SampleHive::ID::BC_Play,
|
||||
wxBitmap(ICON_PLAY_LIGHT_16px, wxBITMAP_TYPE_PNG),
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_pLoopButton = new wxBitmapToggleButton(this, SampleHive::ID::BC_Loop,
|
||||
wxBitmap(ICON_LOOP_LIGHT_16px, wxBITMAP_TYPE_PNG),
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_pStopButton = new wxBitmapButton(this, SampleHive::ID::BC_Stop,
|
||||
wxBitmap(ICON_STOP_LIGHT_16px, wxBITMAP_TYPE_PNG),
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_pMuteButton = new wxBitmapToggleButton(this, SampleHive::ID::BC_Mute,
|
||||
wxBitmap(ICON_MUTE_LIGHT_16px, wxBITMAP_TYPE_PNG),
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pPlayButton = new wxBitmapButton(this, SampleHive::ID::BC_Play,
|
||||
wxBitmap(ICON_PLAY_DARK_16px, wxBITMAP_TYPE_PNG),
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_pLoopButton = new wxBitmapToggleButton(this, SampleHive::ID::BC_Loop,
|
||||
wxBitmap(ICON_LOOP_DARK_16px, wxBITMAP_TYPE_PNG),
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_pStopButton = new wxBitmapButton(this, SampleHive::ID::BC_Stop,
|
||||
wxBitmap(ICON_STOP_DARK_16px, wxBITMAP_TYPE_PNG),
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_pMuteButton = new wxBitmapToggleButton(this, SampleHive::ID::BC_Mute,
|
||||
wxBitmap(ICON_MUTE_DARK_16px, wxBITMAP_TYPE_PNG),
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
}
|
||||
|
||||
m_pPlayButton->SetToolTip(_("Play"));
|
||||
m_pLoopButton->SetToolTip(_("Loop"));
|
||||
m_pStopButton->SetToolTip(_("Stop"));
|
||||
m_pMuteButton->SetToolTip(_("Mute"));
|
||||
|
||||
m_pSettingsButton = new wxButton(this, SampleHive::ID::BC_Settings, _("Settings"), wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_pSettingsButton->SetToolTip(_("Settings"));
|
||||
|
||||
m_pMainSizer->Add(m_pPlayButton, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_pMainSizer->Add(m_pStopButton, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_pMainSizer->Add(m_pLoopButton, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_pMainSizer->Add(m_pLoopABButton, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_pMainSizer->Add(m_pSettingsButton, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_pMainSizer->Add(0,0,1, wxALL | wxEXPAND, 0);
|
||||
m_pMainSizer->Add(m_pSamplePosition, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_pMainSizer->Add(60,0,0, wxALL | wxEXPAND, 0);
|
||||
m_pMainSizer->Add(m_pMuteButton, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_pMainSizer->Add(m_pVolumeSlider, 1, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_pMainSizer->Add(m_pAutoPlayCheck, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
|
||||
this->SetSizer(m_pMainSizer);
|
||||
m_pMainSizer->Fit(this);
|
||||
m_pMainSizer->SetSizeHints(this);
|
||||
m_pMainSizer->Layout();
|
||||
|
||||
Bind(wxEVT_BUTTON, &cTransportControls::OnClickPlay, this, SampleHive::ID::BC_Play);
|
||||
Bind(wxEVT_TOGGLEBUTTON, &cTransportControls::OnClickLoop, this, SampleHive::ID::BC_Loop);
|
||||
Bind(wxEVT_BUTTON, &cTransportControls::OnClickStop, this, SampleHive::ID::BC_Stop);
|
||||
Bind(wxEVT_TOGGLEBUTTON, &cTransportControls::OnClickMute, this, SampleHive::ID::BC_Mute);
|
||||
Bind(wxEVT_BUTTON, &cTransportControls::OnClickSettings, this, SampleHive::ID::BC_Settings);
|
||||
Bind(wxEVT_CHECKBOX, &cTransportControls::OnCheckAutoplay, this, SampleHive::ID::BC_Autoplay);
|
||||
Bind(wxEVT_SCROLL_THUMBTRACK, &cTransportControls::OnSlideVolume, this, SampleHive::ID::BC_Volume);
|
||||
Bind(wxEVT_SCROLL_THUMBRELEASE, &cTransportControls::OnReleaseVolumeSlider, this, SampleHive::ID::BC_Volume);
|
||||
|
||||
// Load control values from config file
|
||||
LoadConfigFile();
|
||||
}
|
||||
|
||||
void cTransportControls::OnClickSettings(wxCommandEvent& event)
|
||||
{
|
||||
cSettings* settings = new cSettings(this);
|
||||
|
||||
switch (settings->ShowModal())
|
||||
{
|
||||
case wxID_OK:
|
||||
if (settings->CanAutoImport())
|
||||
{
|
||||
SampleHive::cUtils::Get().OnAutoImportDir(settings->GetImportDirPath(), this);
|
||||
// RefreshDatabase();
|
||||
}
|
||||
if (settings->IsWaveformColourChanged())
|
||||
{
|
||||
SampleHive::cSignal::SendWaveformUpdateStatus(*this);
|
||||
}
|
||||
break;
|
||||
case wxID_CANCEL:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void cTransportControls::OnClickPlay(wxCommandEvent& event)
|
||||
{
|
||||
m_bStopped = false;
|
||||
|
||||
int selected_row = SampleHive::cHiveData::Get().GetListCtrlSelectedRow();
|
||||
|
||||
if (selected_row < 0)
|
||||
return;
|
||||
|
||||
wxString selection = SampleHive::cHiveData::Get().GetListCtrlTextValue(selected_row, 1);
|
||||
|
||||
// Send custom event to MainFrame to play the sample
|
||||
SampleHive::cSignal::SendCallFunctionPlay(selection, false, *this);
|
||||
}
|
||||
|
||||
void cTransportControls::OnClickLoop(wxCommandEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
m_bLoop = m_pLoopButton->GetValue();
|
||||
|
||||
serializer.SerializeMediaOptions("loop", m_bLoop);
|
||||
}
|
||||
|
||||
void cTransportControls::OnClickStop(wxCommandEvent& event)
|
||||
{
|
||||
if (!m_MediaCtrl.Stop())
|
||||
SH_LOG_ERROR("Error! Unable to stop media.");
|
||||
|
||||
m_bStopped = true;
|
||||
|
||||
// Send custom event to MainFrame to stop the timer
|
||||
SampleHive::cSignal::SendTimerStopStatus(*this);
|
||||
|
||||
m_pSamplePosition->SetLabel("--:--.---/--:--.---");
|
||||
|
||||
// Send custom event to MainFrame to set the statusbar status
|
||||
SampleHive::cSignal::SendSetStatusBarStatus(_("Stopped"), 1, *this);
|
||||
}
|
||||
|
||||
void cTransportControls::OnClickMute(wxCommandEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
if (m_pMuteButton->GetValue())
|
||||
{
|
||||
m_MediaCtrl.SetVolume(0.0);
|
||||
m_bMuted = true;
|
||||
|
||||
serializer.SerializeMediaOptions("muted", m_bMuted);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_MediaCtrl.SetVolume(double(m_pVolumeSlider->GetValue()) / 100);
|
||||
m_bMuted = false;
|
||||
|
||||
serializer.SerializeMediaOptions("muted", m_bMuted);
|
||||
}
|
||||
}
|
||||
|
||||
void cTransportControls::OnCheckAutoplay(wxCommandEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
if (m_pAutoPlayCheck->GetValue())
|
||||
{
|
||||
m_bAutoplay = true;
|
||||
|
||||
serializer.SerializeMediaOptions("autoplay", m_bAutoplay);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bAutoplay = false;
|
||||
|
||||
serializer.SerializeMediaOptions("autoplay", m_bAutoplay);
|
||||
}
|
||||
}
|
||||
|
||||
void cTransportControls::OnSlideVolume(wxScrollEvent& event)
|
||||
{
|
||||
m_MediaCtrl.SetVolume(double(m_pVolumeSlider->GetValue()) / 100);
|
||||
|
||||
// Send custom event to MainFrame to push status to statusbar
|
||||
SampleHive::cSignal::SendPushStatusBarStatus(wxString::Format(_("Volume: %d"), m_pVolumeSlider->GetValue()), 1, *this);
|
||||
}
|
||||
|
||||
void cTransportControls::OnReleaseVolumeSlider(wxScrollEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
serializer.SerializeMediaVolume(m_pVolumeSlider->GetValue());
|
||||
|
||||
int selected_row = SampleHive::cHiveData::Get().GetListCtrlSelectedRow();
|
||||
|
||||
if (selected_row < 0)
|
||||
return;
|
||||
|
||||
wxString selection = SampleHive::cHiveData::Get().GetListCtrlTextValue(selected_row, 1);
|
||||
|
||||
// Wait a second then remove the status from statusbar
|
||||
wxSleep(1);
|
||||
|
||||
// Send custom event to MainFrame to pop status from statusbar
|
||||
SampleHive::cSignal::SendPopStatusBarStatus(1, *this);
|
||||
|
||||
if (m_MediaCtrl.GetState() == wxMEDIASTATE_STOPPED)
|
||||
SampleHive::cSignal::SendSetStatusBarStatus(_("Stopped"), 1, *this);
|
||||
else
|
||||
SampleHive::cSignal::SendPushStatusBarStatus(wxString::Format(_("Now playing: %s"), selection), 1, *this);
|
||||
}
|
||||
|
||||
void cTransportControls::LoadConfigFile()
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
SH_LOG_INFO("Reading transport control values..");
|
||||
|
||||
m_bAutoplay = serializer.DeserializeMediaOptions("autoplay");
|
||||
m_bLoop = serializer.DeserializeMediaOptions("loop");
|
||||
m_bMuted = serializer.DeserializeMediaOptions("muted");
|
||||
|
||||
m_pAutoPlayCheck->SetValue(m_bAutoplay);
|
||||
m_pLoopButton->SetValue(m_bLoop);
|
||||
m_pMuteButton->SetValue(m_bMuted);
|
||||
|
||||
m_pVolumeSlider->SetValue(serializer.DeserializeMediaVolume());
|
||||
|
||||
if (!m_bMuted)
|
||||
m_MediaCtrl.SetVolume(double(m_pVolumeSlider->GetValue()) / 100);
|
||||
else
|
||||
m_MediaCtrl.SetVolume(0.0);
|
||||
}
|
||||
|
||||
cTransportControls::~cTransportControls()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wx/bmpbuttn.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/mediactrl.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/slider.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/tglbtn.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/version.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
class cTransportControls : public wxPanel
|
||||
{
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
cTransportControls(wxWindow* window, wxMediaCtrl& mediaCtrl);
|
||||
~cTransportControls();
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
bool IsLoopABOn() const { return m_pLoopABButton->GetValue(); }
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
inline bool CanAutoplay() const { return m_bAutoplay; };
|
||||
inline bool CanLoop() const { return m_bLoop; };
|
||||
inline bool IsMuted() const { return m_bMuted; };
|
||||
inline bool IsStopped() const { return m_bStopped; };
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void SetLoopABValue(bool value) { m_pLoopABButton->SetValue(value); }
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void SetCanAutoplay(bool autoplay) { m_bAutoplay = autoplay; }
|
||||
void SetCanLoop(bool loop) { m_bLoop = loop; }
|
||||
void SetIsMuted(bool muted) { m_bMuted = muted; }
|
||||
void SetIsStopped(bool stopped) { m_bStopped = stopped; }
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
inline wxString GetSamplePositionText() const { return m_pSamplePosition->GetLabelText(); }
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void SetSamplePositionText(const wxString& text) { m_pSamplePosition->SetLabel(text); }
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
// Event handlers
|
||||
void OnClickPlay(wxCommandEvent& event);
|
||||
void OnClickLoop(wxCommandEvent& event);
|
||||
void OnClickStop(wxCommandEvent& event);
|
||||
void OnClickMute(wxCommandEvent& event);
|
||||
void OnClickSettings(wxCommandEvent& event);
|
||||
void OnCheckAutoplay(wxCommandEvent& event);
|
||||
void OnSlideVolume(wxScrollEvent& event);
|
||||
void OnReleaseVolumeSlider(wxScrollEvent& event);
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
// Load control values from config file
|
||||
void LoadConfigFile();
|
||||
|
||||
void OnAutoImportDir(const wxString& pathToDirectory);
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
wxMediaCtrl& m_MediaCtrl;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
bool m_bAutoplay = false;
|
||||
bool m_bLoop = false;
|
||||
bool m_bMuted = false;
|
||||
bool m_bStopped = false;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
wxBitmapButton* m_pPlayButton = nullptr;
|
||||
wxBitmapToggleButton* m_pLoopButton = nullptr;
|
||||
wxBitmapButton* m_pStopButton = nullptr;
|
||||
wxButton* m_pSettingsButton = nullptr;
|
||||
wxBitmapToggleButton* m_pMuteButton = nullptr;
|
||||
wxBitmapToggleButton* m_pLoopABButton = nullptr;
|
||||
wxStaticText* m_pSamplePosition = nullptr;
|
||||
wxSlider* m_pVolumeSlider = nullptr;
|
||||
wxCheckBox* m_pAutoPlayCheck = nullptr;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
wxBoxSizer* m_pMainSizer = nullptr;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
wxSystemAppearance m_Theme = wxSystemSettings::GetAppearance();
|
||||
};
|
||||
|
|
@ -0,0 +1,307 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "GUI/Trash.hpp"
|
||||
#include "Database/Database.hpp"
|
||||
#include "Utility/ControlIDs.hpp"
|
||||
#include "Utility/HiveData.hpp"
|
||||
#include "Utility/Log.hpp"
|
||||
#include "Utility/Paths.hpp"
|
||||
#include "Utility/Signal.hpp"
|
||||
#include "Utility/Serialize.hpp"
|
||||
#include "Utility/Utils.hpp"
|
||||
|
||||
#include <exception>
|
||||
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/menu.h>
|
||||
#include <wx/msgdlg.h>
|
||||
|
||||
cTrashPanel::cTrashPanel(wxWindow* window)
|
||||
: wxPanel(window, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL),
|
||||
m_pWindow(window)
|
||||
{
|
||||
m_pMainSizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_pTrashSizer = new wxBoxSizer(wxVERTICAL);
|
||||
m_pButtonSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
m_pTrash = new wxTreeCtrl(this, SampleHive::ID::BC_Trash, wxDefaultPosition, wxDefaultSize,
|
||||
wxTR_NO_BUTTONS | wxTR_HIDE_ROOT | wxTR_MULTIPLE);
|
||||
|
||||
// Setting m_Trash to accept files to be dragged and dropped on it
|
||||
m_pTrash->DragAcceptFiles(true);
|
||||
|
||||
m_pTrashSizer->Add(m_pTrash, wxSizerFlags(1).Expand());
|
||||
|
||||
m_pRestoreTrashedItemButton = new wxButton(this, SampleHive::ID::BC_RestoreTrashedItem, _("Restore sample"),
|
||||
wxDefaultPosition, wxDefaultSize, 0);
|
||||
m_pRestoreTrashedItemButton->SetToolTip(_("Restore selected sample"));
|
||||
|
||||
m_pButtonSizer->Add(m_pRestoreTrashedItemButton, wxSizerFlags(1).Expand());
|
||||
|
||||
// Addubg root to TrashedItems
|
||||
m_TrashRoot = m_pTrash->AddRoot("Trash");
|
||||
|
||||
m_pTrash->Connect(wxEVT_DROP_FILES, wxDropFilesEventHandler(cTrashPanel::OnDragAndDropToTrash), NULL, this);
|
||||
Bind(wxEVT_TREE_ITEM_RIGHT_CLICK, &cTrashPanel::OnShowTrashContextMenu, this, SampleHive::ID::BC_Trash);
|
||||
Bind(wxEVT_BUTTON, &cTrashPanel::OnClickRestoreTrashItem, this, SampleHive::ID::BC_RestoreTrashedItem);
|
||||
|
||||
m_pMainSizer->Add(m_pTrashSizer, wxSizerFlags(1).Expand());
|
||||
m_pMainSizer->Add(m_pButtonSizer, wxSizerFlags(0).Expand());
|
||||
|
||||
// Sizer for trash pane
|
||||
this->SetSizer(m_pMainSizer);
|
||||
m_pMainSizer->Fit(this);
|
||||
m_pMainSizer->SetSizeHints(this);
|
||||
m_pMainSizer->Layout();
|
||||
}
|
||||
|
||||
void cTrashPanel::OnDragAndDropToTrash(wxDropFilesEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
cDatabase db;
|
||||
|
||||
if (event.GetNumberOfFiles() > 0)
|
||||
{
|
||||
wxFileDataObject file_data;
|
||||
wxArrayString files;
|
||||
|
||||
wxDataViewItemArray items;
|
||||
int rows = SampleHive::cHiveData::Get().GetListCtrlSelections(items);
|
||||
|
||||
wxString msg;
|
||||
|
||||
wxDataViewItem root = wxDataViewItem(wxNullPtr);
|
||||
wxDataViewItem container, child;
|
||||
|
||||
for (int i = 0; i < rows; i++)
|
||||
{
|
||||
int item_row = SampleHive::cHiveData::Get().GetListCtrlRowFromItem(items, i);
|
||||
|
||||
wxString text_value = SampleHive::cHiveData::Get().GetListCtrlTextValue(item_row, 1);
|
||||
|
||||
std::string multi_selection = serializer.DeserializeShowFileExtension() ?
|
||||
SampleHive::cHiveData::Get().GetListCtrlTextValue(item_row, 1).BeforeLast('.').ToStdString() :
|
||||
SampleHive::cHiveData::Get().GetListCtrlTextValue(item_row, 1).ToStdString() ;
|
||||
|
||||
file_data.AddFile(multi_selection);
|
||||
|
||||
files = file_data.GetFilenames();
|
||||
|
||||
if (db.GetFavoriteColumnValueByFilename(files[i].ToStdString()))
|
||||
{
|
||||
SampleHive::cHiveData::Get().ListCtrlSetVariant(wxVariant(wxBitmap(ICON_STAR_EMPTY_16px, wxBITMAP_TYPE_PNG)), item_row, 0);
|
||||
|
||||
db.UpdateFavoriteColumn(files[i].ToStdString(), 0);
|
||||
|
||||
for (int j = 0; j < SampleHive::cHiveData::Get().GetHiveChildCount(root); j++)
|
||||
{
|
||||
container = SampleHive::cHiveData::Get().GetHiveNthChild(root, j);
|
||||
|
||||
for (int k = 0; k < SampleHive::cHiveData::Get().GetHiveChildCount(container); k++)
|
||||
{
|
||||
child = SampleHive::cHiveData::Get().GetHiveNthChild(container, k);
|
||||
|
||||
wxString child_text = serializer.DeserializeShowFileExtension() ?
|
||||
SampleHive::cHiveData::Get().GetHiveItemText(child).BeforeLast('.') :
|
||||
SampleHive::cHiveData::Get().GetHiveItemText(child);
|
||||
|
||||
if (child_text == files[i])
|
||||
{
|
||||
SampleHive::cHiveData::Get().HiveDeleteItem(child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
db.UpdateTrashColumn(files[i].ToStdString(), 1);
|
||||
db.UpdateHiveName(files[i].ToStdString(),
|
||||
SampleHive::cHiveData::Get().GetHiveItemText(SampleHive::cHiveData::Get().GetFavoritesHive()).ToStdString());
|
||||
|
||||
m_pTrash->AppendItem(m_TrashRoot, text_value);
|
||||
|
||||
SampleHive::cHiveData::Get().ListCtrlDeleteItem(item_row);
|
||||
|
||||
msg = wxString::Format(_("%s sent to trash"), text_value);
|
||||
}
|
||||
|
||||
if (!msg.IsEmpty())
|
||||
SampleHive::cSignal::SendInfoBarMessage(msg, wxICON_ERROR, *this);
|
||||
}
|
||||
}
|
||||
|
||||
void cTrashPanel::OnShowTrashContextMenu(wxTreeEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
cDatabase db;
|
||||
|
||||
wxTreeItemId selected_trashed_item = event.GetItem();
|
||||
|
||||
wxMenu menu;
|
||||
|
||||
menu.Append(SampleHive::ID::MN_DeleteTrash, _("Delete from database"), _("Delete the selected sample(s) from database"));
|
||||
menu.Append(SampleHive::ID::MN_RestoreTrashedItem, _("Restore sample"), _("Restore the selected sample(s) back to library"));
|
||||
|
||||
if (selected_trashed_item.IsOk())
|
||||
{
|
||||
switch (m_pTrash->GetPopupMenuSelectionFromUser(menu, event.GetPoint()))
|
||||
{
|
||||
case SampleHive::ID::MN_DeleteTrash:
|
||||
{
|
||||
wxString trashed_item_name = serializer.DeserializeShowFileExtension() ?
|
||||
m_pTrash->GetItemText(selected_trashed_item).BeforeLast('.') :
|
||||
m_pTrash->GetItemText(selected_trashed_item);
|
||||
|
||||
db.RemoveSampleFromDatabase(trashed_item_name.ToStdString());
|
||||
|
||||
m_pTrash->Delete(selected_trashed_item);
|
||||
|
||||
SH_LOG_INFO("{} deleted from trash and databse", trashed_item_name.ToStdString());
|
||||
}
|
||||
break;
|
||||
case SampleHive::ID::MN_RestoreTrashedItem:
|
||||
{
|
||||
wxArrayTreeItemIds selected_item_ids;
|
||||
m_pTrash->GetSelections(selected_item_ids);
|
||||
|
||||
wxFileDataObject file_data;
|
||||
wxArrayString files;
|
||||
|
||||
wxString selected_item_text;
|
||||
std::string filename;
|
||||
|
||||
for (size_t i = 0; i < selected_item_ids.GetCount(); i++)
|
||||
{
|
||||
selected_item_text = m_pTrash->GetItemText(selected_item_ids[i]);
|
||||
|
||||
filename = SampleHive::cUtils::Get().GetFilenamePathAndExtension(selected_item_text).Filename;
|
||||
|
||||
file_data.AddFile(filename);
|
||||
|
||||
files = file_data.GetFilenames();
|
||||
|
||||
db.UpdateTrashColumn(files[i].ToStdString(), 0);
|
||||
|
||||
try
|
||||
{
|
||||
wxVector<wxVector<wxVariant>> dataset;
|
||||
|
||||
if (db.RestoreFromTrashByFilename(files[i].ToStdString(),
|
||||
dataset,
|
||||
serializer.DeserializeShowFileExtension(),
|
||||
ICON_STAR_FILLED_16px, ICON_STAR_EMPTY_16px).empty())
|
||||
{
|
||||
SH_LOG_INFO("Error! Database is empty.");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto data : dataset)
|
||||
{
|
||||
SampleHive::cHiveData::Get().ListCtrlAppendItem(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
SH_LOG_ERROR("Error loading data. {}", e.what());
|
||||
}
|
||||
|
||||
m_pTrash->Delete(selected_item_ids[i]);
|
||||
|
||||
SH_LOG_INFO("{} restored from trash", files[i].ToStdString());
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cTrashPanel::OnClickRestoreTrashItem(wxCommandEvent& event)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
cDatabase db;
|
||||
|
||||
wxArrayTreeItemIds selected_item_ids;
|
||||
m_pTrash->GetSelections(selected_item_ids);
|
||||
|
||||
wxFileDataObject file_data;
|
||||
wxArrayString files;
|
||||
|
||||
wxString selected_item_text;
|
||||
std::string filename;
|
||||
|
||||
if (m_pTrash->GetChildrenCount(m_TrashRoot) == 0)
|
||||
{
|
||||
wxMessageBox(_("Trash is empty, nothing to restore!"), wxMessageBoxCaptionStr, wxOK | wxCENTRE, this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (selected_item_ids.IsEmpty())
|
||||
{
|
||||
wxMessageBox(_("No item selected, try selected a item first."), wxMessageBoxCaptionStr, wxOK | wxCENTRE, this);
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < selected_item_ids.GetCount(); i++)
|
||||
{
|
||||
selected_item_text = m_pTrash->GetItemText(selected_item_ids[i]);
|
||||
|
||||
filename = SampleHive::cUtils::Get().GetFilenamePathAndExtension(selected_item_text).Filename;
|
||||
|
||||
file_data.AddFile(filename);
|
||||
|
||||
files = file_data.GetFilenames();
|
||||
|
||||
db.UpdateTrashColumn(files[i].ToStdString(), 0);
|
||||
|
||||
try
|
||||
{
|
||||
wxVector<wxVector<wxVariant>> dataset;
|
||||
|
||||
if (db.RestoreFromTrashByFilename(files[i].ToStdString(), dataset,
|
||||
serializer.DeserializeShowFileExtension(),
|
||||
ICON_STAR_FILLED_16px, ICON_STAR_EMPTY_16px).empty())
|
||||
{
|
||||
SH_LOG_INFO("Error! Database is empty.");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto data : dataset)
|
||||
{
|
||||
SampleHive::cHiveData::Get().ListCtrlAppendItem(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
SH_LOG_ERROR("Error loading data. {}", e.what());
|
||||
}
|
||||
|
||||
m_pTrash->Delete(selected_item_ids[i]);
|
||||
}
|
||||
}
|
||||
|
||||
cTrashPanel::~cTrashPanel()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wx/button.h>
|
||||
#include <wx/dataview.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/treebase.h>
|
||||
#include <wx/treectrl.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
class cTrashPanel : public wxPanel
|
||||
{
|
||||
public:
|
||||
cTrashPanel(wxWindow* window);
|
||||
~cTrashPanel();
|
||||
|
||||
public:
|
||||
wxTreeCtrl* GetTrashObject() { return m_pTrash; }
|
||||
wxTreeItemId& GetTrashRoot() { return m_TrashRoot; }
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
// TrashPane event handlers
|
||||
void OnShowTrashContextMenu(wxTreeEvent& event);
|
||||
void OnClickRestoreTrashItem(wxCommandEvent& event);
|
||||
void OnDragAndDropToTrash(wxDropFilesEvent& event);
|
||||
|
||||
private:
|
||||
wxTreeItemId m_TrashRoot;
|
||||
wxTreeCtrl* m_pTrash = nullptr;
|
||||
wxButton* m_pRestoreTrashedItemButton = nullptr;
|
||||
wxBoxSizer* m_pMainSizer = nullptr;
|
||||
wxBoxSizer* m_pTrashSizer = nullptr;
|
||||
wxBoxSizer* m_pButtonSizer = nullptr;
|
||||
|
||||
private:
|
||||
wxWindow* m_pWindow = nullptr;
|
||||
};
|
||||
|
|
@ -0,0 +1,475 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "GUI/WaveformViewer.hpp"
|
||||
#include "Utility/HiveData.hpp"
|
||||
#include "Utility/Log.hpp"
|
||||
#include "Utility/Paths.hpp"
|
||||
#include "Utility/Utils.hpp"
|
||||
#include "Utility/Serialize.hpp"
|
||||
#include "Utility/Event.hpp"
|
||||
#include "Utility/Signal.hpp"
|
||||
#include "Utility/Tags.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
#include <exception>
|
||||
#include <vector>
|
||||
|
||||
#include <wx/brush.h>
|
||||
#include <wx/dcclient.h>
|
||||
#include <wx/defs.h>
|
||||
#include <wx/dcmemory.h>
|
||||
#include <wx/filefn.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/pen.h>
|
||||
|
||||
#include <sndfile.h>
|
||||
#include <sndfile.hh>
|
||||
|
||||
cWaveformViewer::cWaveformViewer(wxWindow* window, wxMediaCtrl& mediaCtrl)
|
||||
: wxPanel(window, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL | wxNO_BORDER | wxFULL_REPAINT_ON_RESIZE),
|
||||
m_Window(window), m_MediaCtrl(mediaCtrl)
|
||||
{
|
||||
this->SetDoubleBuffered(true);
|
||||
|
||||
Bind(wxEVT_PAINT, &cWaveformViewer::OnPaint, this);
|
||||
Bind(wxEVT_MOTION, &cWaveformViewer::OnMouseMotion, this);
|
||||
Bind(wxEVT_LEFT_DOWN, &cWaveformViewer::OnMouseLeftButtonDown, this);
|
||||
Bind(wxEVT_LEFT_UP, &cWaveformViewer::OnMouseLeftButtonUp, this);
|
||||
// Bind(wxEVT_KEY_DOWN, &cWaveformViewer::OnControlKeyDown, this);
|
||||
Bind(wxEVT_KEY_UP, &cWaveformViewer::OnControlKeyUp, this);
|
||||
|
||||
m_Sizer = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
this->SetSizer(m_Sizer);
|
||||
m_Sizer->Fit(this);
|
||||
m_Sizer->SetSizeHints(this);
|
||||
m_Sizer->Layout();
|
||||
}
|
||||
|
||||
cWaveformViewer::~cWaveformViewer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void cWaveformViewer::OnPaint(wxPaintEvent& event)
|
||||
{
|
||||
wxPaintDC dc(this);
|
||||
|
||||
const wxSize& size = m_Window->GetClientSize();
|
||||
|
||||
if (!m_WaveformBitmap.IsOk()
|
||||
|| m_WaveformBitmap.GetWidth() != size.x
|
||||
|| m_WaveformBitmap.GetHeight() != size.y
|
||||
|| bBitmapDirty)
|
||||
{
|
||||
SH_LOG_INFO("Updating waveform bitmap..");
|
||||
|
||||
m_WaveformBitmap = wxBitmap(wxImage(size.x, size.y), 32);
|
||||
|
||||
UpdateWaveformBitmap();
|
||||
|
||||
bBitmapDirty = false;
|
||||
}
|
||||
|
||||
dc.DrawBitmap(m_WaveformBitmap, 0, 0, false);
|
||||
|
||||
RenderPlayhead(dc);
|
||||
|
||||
// Draw selection range
|
||||
if (bSelectRange)
|
||||
{
|
||||
wxRect rect(m_CurrentPoint, m_AnchorPoint);
|
||||
|
||||
dc.SetPen(wxPen(wxColour(200, 200, 200), 2, wxPENSTYLE_SOLID));
|
||||
dc.SetBrush(wxBrush(wxColour(200, 200, 200, 80), wxBRUSHSTYLE_SOLID));
|
||||
dc.DrawRectangle(rect);
|
||||
}
|
||||
|
||||
// Draw selected area
|
||||
if (!bSelectRange && bDrawSelectedArea && !bBitmapDirty)
|
||||
{
|
||||
dc.SetPen(wxPen(wxColour(200, 200, 200, 255), 4, wxPENSTYLE_SOLID));
|
||||
dc.SetBrush(wxBrush(wxColour(200, 200, 200, 80), wxBRUSHSTYLE_SOLID));
|
||||
dc.DrawRectangle(wxRect(m_AnchorPoint.x, -2, m_CurrentPoint.x - m_AnchorPoint.x,
|
||||
this->GetSize().GetHeight() + 5));
|
||||
|
||||
bAreaSelected = true;
|
||||
// SendLoopPoints();
|
||||
SampleHive::cSignal::SendLoopPoints(CalculateLoopPoints(), *this);
|
||||
}
|
||||
else
|
||||
bAreaSelected = false;
|
||||
}
|
||||
|
||||
void cWaveformViewer::RenderPlayhead(wxDC& dc)
|
||||
{
|
||||
int selected_row = SampleHive::cHiveData::Get().GetListCtrlSelectedRow();
|
||||
|
||||
if (selected_row < 0)
|
||||
return;
|
||||
|
||||
wxString selected = SampleHive::cHiveData::Get().GetListCtrlTextValue(selected_row, 1);
|
||||
std::string path = SampleHive::cUtils::Get().GetFilenamePathAndExtension(selected).Path.ToStdString();
|
||||
|
||||
SampleHive::cTags tags(path);
|
||||
|
||||
int length = tags.GetAudioInfo().length;
|
||||
|
||||
double position = m_MediaCtrl.Tell();
|
||||
|
||||
int panel_width = this->GetSize().GetWidth();
|
||||
double line_pos = panel_width * (position / length);
|
||||
|
||||
m_PlayheadColour = wxColor(255, 0, 0, 255);
|
||||
|
||||
// Draw the triangle
|
||||
dc.SetPen(wxPen(m_PlayheadColour, 8, wxPENSTYLE_SOLID));
|
||||
dc.DrawLine(line_pos - 5, this->GetSize().GetHeight() - (this->GetSize().GetHeight() - 1),
|
||||
line_pos, this->GetSize().GetHeight() - (this->GetSize().GetHeight() - 1) + 5);
|
||||
dc.DrawLine(line_pos + 5, this->GetSize().GetHeight() - (this->GetSize().GetHeight() - 1),
|
||||
line_pos, this->GetSize().GetHeight() - (this->GetSize().GetHeight()- 1) + 5);
|
||||
|
||||
// Draw the line
|
||||
dc.SetPen(wxPen(m_PlayheadColour, 2, wxPENSTYLE_SOLID));
|
||||
dc.DrawLine(line_pos, this->GetSize().GetHeight() - (this->GetSize().GetHeight() - 1), line_pos, this->GetSize().GetHeight() - 1);
|
||||
}
|
||||
|
||||
void cWaveformViewer::UpdateWaveformBitmap()
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
|
||||
int selected_row = SampleHive::cHiveData::Get().GetListCtrlSelectedRow();
|
||||
|
||||
if (selected_row < 0)
|
||||
return;
|
||||
|
||||
wxString selection = SampleHive::cHiveData::Get().GetListCtrlTextValue(selected_row, 1);
|
||||
|
||||
wxString path = SampleHive::cUtils::Get().GetFilenamePathAndExtension(selection).Path;
|
||||
|
||||
SndfileHandle snd_file(path.ToStdString().c_str());
|
||||
|
||||
int channels = snd_file.channels();
|
||||
double sample_rate = snd_file.samplerate();
|
||||
sf_count_t frames = snd_file.frames();
|
||||
|
||||
std::vector<float> sample;
|
||||
sample.resize(frames * channels);
|
||||
|
||||
std::vector<float> waveform;
|
||||
|
||||
try
|
||||
{
|
||||
// TODO, FIXME: Don't reload file on every window resize
|
||||
snd_file.read(&sample.at(0), frames * channels);
|
||||
|
||||
float display_width = this->GetSize().GetWidth();
|
||||
float display_height = this->GetSize().GetHeight();
|
||||
|
||||
SH_LOG_INFO("Calculating Waveform bars RMS..");
|
||||
|
||||
float chunk_size = (float)(frames) / (float)display_width;
|
||||
int number_of_chunks = static_cast<int>(static_cast<float>(frames) / chunk_size);
|
||||
|
||||
// Start with low non-zero value
|
||||
float normalize = 0.00001;
|
||||
|
||||
for (int i = 0; i < number_of_chunks; i++)
|
||||
{
|
||||
double sum = 0, mono = 0;
|
||||
|
||||
int start_point = static_cast<int>(i * chunk_size * channels);
|
||||
|
||||
// Iterate on the chunk, get the square of sum of monos
|
||||
for (int j = 0; j < chunk_size; j++)
|
||||
{
|
||||
if (channels == 2)
|
||||
mono = 0.5f * (sample[start_point + (2 * j)] + sample[start_point + (2 * j) + 1]);
|
||||
else
|
||||
mono = sample[start_point + j];
|
||||
|
||||
sum += mono * mono; // Square
|
||||
}
|
||||
|
||||
sum /= chunk_size; // Mean
|
||||
sum = pow(sum, 0.5); // Root
|
||||
|
||||
// We might bleed a bit on the end and get some near infs, dunno
|
||||
// what is causing astronomically big numbers from sample[]
|
||||
if ((sum < 200.0) && (sum > normalize))
|
||||
normalize = sum;
|
||||
|
||||
waveform.push_back(sum);
|
||||
}
|
||||
|
||||
// Actually normalize
|
||||
for (size_t i = 0; i < waveform.size(); i++)
|
||||
waveform[i] /= normalize;
|
||||
|
||||
// Draw code
|
||||
wxMemoryDC mdc(m_WaveformBitmap);
|
||||
|
||||
mdc.SetBackground(wxBrush(wxColour(0, 0, 0, 150), wxBRUSHSTYLE_SOLID));
|
||||
mdc.Clear();
|
||||
|
||||
m_WaveformColour = serializer.DeserializeWaveformColour();
|
||||
|
||||
mdc.SetPen(wxPen(wxColour(m_WaveformColour), 2, wxPENSTYLE_SOLID));
|
||||
|
||||
SH_LOG_DEBUG("Drawing bitmap..");
|
||||
|
||||
for (size_t i = 0; i < waveform.size() - 1; i++)
|
||||
{
|
||||
float half_display_height = static_cast<float>(display_height) / 2.0f;
|
||||
|
||||
// X is percentage of i relative to waveform.size() multiplied by
|
||||
// the width, Y is the half height times the value up or down
|
||||
float X = display_width * ((float)i / waveform.size());
|
||||
float Y = waveform[i] * half_display_height;
|
||||
|
||||
mdc.DrawLine(X, half_display_height + Y, X, half_display_height - Y);
|
||||
}
|
||||
|
||||
SH_LOG_DEBUG("Done drawing bitmap..");
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
SH_LOG_ERROR("Error! SNDFILE {}", e.what());
|
||||
SH_LOG_ERROR("Error! SNDFILE {}", sf_strerror(snd_file.rawHandle()));
|
||||
}
|
||||
}
|
||||
|
||||
void cWaveformViewer::OnControlKeyDown(wxKeyEvent &event)
|
||||
{
|
||||
switch (event.GetKeyCode())
|
||||
{
|
||||
case WXK_CONTROL:
|
||||
SetCursor(wxCURSOR_IBEAM);
|
||||
break;
|
||||
default:
|
||||
SetCursor(wxCURSOR_ARROW);
|
||||
break;
|
||||
}
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void cWaveformViewer::OnControlKeyUp(wxKeyEvent &event)
|
||||
{
|
||||
switch (event.GetKeyCode())
|
||||
{
|
||||
case WXK_CONTROL:
|
||||
if (bSelectRange)
|
||||
{
|
||||
SetCursor(wxCURSOR_ARROW);
|
||||
|
||||
bSelectRange = false;
|
||||
bDrawSelectedArea = false;
|
||||
|
||||
ReleaseMouse();
|
||||
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void cWaveformViewer::OnMouseMotion(wxMouseEvent& event)
|
||||
{
|
||||
int selected_row = SampleHive::cHiveData::Get().GetListCtrlSelectedRow();
|
||||
|
||||
if (selected_row < 0)
|
||||
return;
|
||||
|
||||
wxString selected = SampleHive::cHiveData::Get().GetListCtrlTextValue(selected_row, 1);
|
||||
std::string path = SampleHive::cUtils::Get().GetFilenamePathAndExtension(selected).Path.ToStdString();
|
||||
|
||||
SampleHive::cTags tags(path);
|
||||
|
||||
int length = tags.GetAudioInfo().length;
|
||||
|
||||
double position = m_MediaCtrl.Tell();
|
||||
|
||||
int panel_width = this->GetSize().GetWidth();
|
||||
double line_pos = panel_width * (position / length);
|
||||
|
||||
wxPoint pos = event.GetPosition();
|
||||
|
||||
double seek_to = ((double)pos.x / panel_width) * length;
|
||||
|
||||
if (abs(pos.x - line_pos) <= 5 && pos.y <= 5)
|
||||
{
|
||||
SetCursor(wxCursor(wxCURSOR_HAND));
|
||||
SH_LOG_DEBUG("Cursor on playhead..");
|
||||
}
|
||||
else if (bSelectRange)
|
||||
{
|
||||
m_CurrentPoint = wxPoint(pos.x , pos.y);
|
||||
|
||||
Refresh();
|
||||
|
||||
SH_LOG_INFO("CTRL pressed, pressing LMB will draw selection range at {}, {}", pos.x, pos.y);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
void cWaveformViewer::OnMouseLeftButtonDown(wxMouseEvent& event)
|
||||
{
|
||||
int selected_row = SampleHive::cHiveData::Get().GetListCtrlSelectedRow();
|
||||
|
||||
if (selected_row < 0)
|
||||
return;
|
||||
|
||||
wxString selected = SampleHive::cHiveData::Get().GetListCtrlTextValue(selected_row, 1);
|
||||
std::string path = SampleHive::cUtils::Get().GetFilenamePathAndExtension(selected).Path.ToStdString();
|
||||
|
||||
SampleHive::cTags tags(path);
|
||||
|
||||
int length = tags.GetAudioInfo().length;
|
||||
|
||||
double position = m_MediaCtrl.Tell();
|
||||
|
||||
int panel_width = this->GetSize().GetWidth();
|
||||
double line_pos = panel_width * (position / length);
|
||||
|
||||
wxPoint pos = event.GetPosition();
|
||||
|
||||
if (abs(pos.x - line_pos) <= 5 && pos.y <= 5)
|
||||
{
|
||||
SetCursor(wxCURSOR_CLOSED_HAND);
|
||||
CaptureMouse();
|
||||
|
||||
SH_LOG_DEBUG("Mouse Captured playhead..");
|
||||
}
|
||||
else if (event.ControlDown())
|
||||
{
|
||||
SH_LOG_DEBUG("LMB pressed");
|
||||
|
||||
SetCursor(wxCURSOR_CLOSED_HAND);
|
||||
CaptureMouse();
|
||||
|
||||
bSelectRange = true;
|
||||
|
||||
m_AnchorPoint = wxPoint(pos.x, pos.y);
|
||||
m_CurrentPoint = m_AnchorPoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCursor(wxCURSOR_ARROW);
|
||||
return;
|
||||
}
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
void cWaveformViewer::OnMouseLeftButtonUp(wxMouseEvent& event)
|
||||
{
|
||||
int selected_row = SampleHive::cHiveData::Get().GetListCtrlSelectedRow();
|
||||
|
||||
if (selected_row < 0)
|
||||
return;
|
||||
|
||||
wxString selected = SampleHive::cHiveData::Get().GetListCtrlTextValue(selected_row, 1);
|
||||
std::string path = SampleHive::cUtils::Get().GetFilenamePathAndExtension(selected).Path.ToStdString();
|
||||
|
||||
SampleHive::cTags tags(path);
|
||||
|
||||
int length = tags.GetAudioInfo().length;
|
||||
|
||||
double position = m_MediaCtrl.Tell();
|
||||
|
||||
int panel_width = this->GetSize().GetWidth();
|
||||
double line_pos = panel_width * (position / length);
|
||||
|
||||
wxPoint pos = event.GetPosition();
|
||||
|
||||
double seek_to = ((double)pos.x / panel_width) * length;
|
||||
|
||||
if (!wxWindow::HasCapture())
|
||||
{
|
||||
SH_LOG_INFO("Window doesn't have capture skipping..");
|
||||
return;
|
||||
}
|
||||
|
||||
if (bSelectRange)
|
||||
{
|
||||
SH_LOG_DEBUG("LMB released");
|
||||
|
||||
m_CurrentPoint = wxPoint(pos.x, pos.y);
|
||||
|
||||
ReleaseMouse();
|
||||
SetCursor(wxCURSOR_ARROW);
|
||||
|
||||
Refresh();
|
||||
|
||||
bSelectRange = false;
|
||||
|
||||
if (!bSelectRange)
|
||||
bDrawSelectedArea = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ReleaseMouse();
|
||||
SetCursor(wxCURSOR_ARROW);
|
||||
|
||||
m_MediaCtrl.Seek(seek_to, wxFromStart);
|
||||
SampleHive::cSignal::SendPushStatusBarStatus(wxString::Format(_("Now playing: %s"), selected), 1, *this);
|
||||
SampleHive::cSignal::SendCallFunctionPlay(selected, false, *this);
|
||||
}
|
||||
}
|
||||
|
||||
void cWaveformViewer::ResetBitmapDC()
|
||||
{
|
||||
bBitmapDirty = true;
|
||||
bSelectRange = false;
|
||||
bDrawSelectedArea = false;
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
std::pair<double, double> cWaveformViewer::CalculateLoopPoints()
|
||||
{
|
||||
int selected_row = SampleHive::cHiveData::Get().GetListCtrlSelectedRow();
|
||||
|
||||
if (selected_row < 0)
|
||||
return { 0.0, 0.0 };
|
||||
|
||||
wxString selected = SampleHive::cHiveData::Get().GetListCtrlTextValue(selected_row, 1);
|
||||
std::string path = SampleHive::cUtils::Get().GetFilenamePathAndExtension(selected).Path.ToStdString();
|
||||
|
||||
SampleHive::cTags tags(path);
|
||||
|
||||
int length = tags.GetAudioInfo().length;
|
||||
|
||||
int panel_width = this->GetSize().GetWidth();
|
||||
|
||||
int a = m_AnchorPoint.x, b = m_CurrentPoint.x;
|
||||
|
||||
double loopA = ((double)a / panel_width) * length;
|
||||
double loopB = ((double)b / panel_width) * length;
|
||||
|
||||
return { loopA, loopB };
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/colour.h>
|
||||
#include <wx/dc.h>
|
||||
#include <wx/event.h>
|
||||
#include <wx/mediactrl.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/statusbr.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
class cWaveformViewer : public wxPanel
|
||||
{
|
||||
public:
|
||||
cWaveformViewer(wxWindow* window, wxMediaCtrl& mediaCtrl);
|
||||
~cWaveformViewer();
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
wxWindow* m_Window;
|
||||
|
||||
wxBoxSizer* m_Sizer;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
wxMediaCtrl& m_MediaCtrl;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
wxBitmap m_WaveformBitmap;
|
||||
wxColour m_PlayheadColour;
|
||||
wxColour m_WaveformColour;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Selection area coordinates
|
||||
wxPoint m_AnchorPoint;
|
||||
wxPoint m_CurrentPoint;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
bool bBitmapDirty = false;
|
||||
bool bSelectRange = false;
|
||||
bool bDrawSelectedArea = false;
|
||||
bool bAreaSelected = false;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
void RenderPlayhead(wxDC& dc);
|
||||
void UpdateWaveformBitmap();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void OnMouseMotion(wxMouseEvent& event);
|
||||
void OnMouseLeftButtonDown(wxMouseEvent& event);
|
||||
void OnMouseLeftButtonUp(wxMouseEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void OnControlKeyUp(wxKeyEvent& event);
|
||||
void OnControlKeyDown(wxKeyEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
std::pair<double, double> CalculateLoopPoints();
|
||||
|
||||
float GetBPM(const std::string& path);
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
void ResetBitmapDC();
|
||||
};
|
||||
2861
src/MainFrame.cpp
|
|
@ -1,269 +0,0 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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/event.h>
|
||||
#include <wx/frame.h>
|
||||
#include <wx/fswatcher.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/statbmp.h>
|
||||
#include <wx/statusbr.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 <taglib/taglib.h>
|
||||
#include <taglib/fileref.h>
|
||||
#include <taglib/tstring.h>
|
||||
|
||||
struct FileInfo
|
||||
{
|
||||
wxString Path;
|
||||
std::string Extension;
|
||||
std::string Filename;
|
||||
};
|
||||
|
||||
class MainFrame : public wxFrame
|
||||
{
|
||||
public:
|
||||
MainFrame();
|
||||
~MainFrame();
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
// Main Panel
|
||||
wxPanel* m_MainPanel;
|
||||
wxBoxSizer* m_MainSizer;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Hive bitmap icon for the statusbar
|
||||
wxStaticBitmap* m_HiveBitmap;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// App statusbar
|
||||
wxStatusBar* m_StatusBar;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// App menubar
|
||||
wxMenuBar* m_MenuBar;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Menu and menu items for the menubar
|
||||
wxMenu* m_FileMenu;
|
||||
wxMenu* m_EditMenu;
|
||||
wxMenu* m_ViewMenu;
|
||||
wxMenu* m_HelpMenu;
|
||||
wxMenuItem* m_AddFile;
|
||||
wxMenuItem* m_AddDirectory;
|
||||
wxMenuItem* m_ToggleExtension;
|
||||
wxMenuItem* m_ToggleMenuBar;
|
||||
wxMenuItem* m_ToggleStatusBar;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Splitter windows
|
||||
wxSplitterWindow* m_TopSplitter;
|
||||
wxSplitterWindow* m_BottomSplitter;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Top panel controls
|
||||
wxPanel* m_TopPanel;
|
||||
wxBoxSizer* m_TopSizer;
|
||||
wxBoxSizer* m_TopPanelMainSizer;
|
||||
wxBoxSizer* m_WaveformDisplaySizer;
|
||||
wxStaticBitmap* 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_HivesPanel;
|
||||
wxPanel* m_TrashPanel;
|
||||
wxNotebook* m_Notebook;
|
||||
wxBoxSizer* m_BottomLeftPanelMainSizer;
|
||||
wxBoxSizer* m_HivesMainSizer;
|
||||
wxBoxSizer* m_HivesFavoritesSizer;
|
||||
wxBoxSizer* m_HivesButtonSizer;
|
||||
wxBoxSizer* m_TrashMainSizer;
|
||||
wxBoxSizer* m_TrashItemSizer;
|
||||
wxBoxSizer* m_TrashButtonSizer;
|
||||
wxDirCtrl* m_DirCtrl;
|
||||
wxDataViewTreeCtrl* m_Hives;
|
||||
wxDataViewItem favorites_hive;
|
||||
wxTreeItemId trash_root;
|
||||
wxTreeCtrl* m_Trash;
|
||||
wxButton* m_AddHiveButton;
|
||||
wxButton* m_RemoveHiveButton;
|
||||
wxButton* m_RestoreTrashedItemButton;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Right panel controls
|
||||
wxPanel* m_BottomRightPanel;
|
||||
wxBoxSizer* m_BottomRightPanelMainSizer;
|
||||
wxSearchCtrl* m_SearchBox;
|
||||
wxInfoBar* m_InfoBar;
|
||||
wxDataViewListCtrl* m_Library;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// MediaCtrl
|
||||
wxMediaCtrl* m_MediaCtrl;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Timer
|
||||
wxTimer* m_Timer;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// FileSystemWatcher
|
||||
wxFileSystemWatcher* m_FsWatcher;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
bool bAutoplay = false;
|
||||
bool bLoop = false;
|
||||
bool bMuted = false;
|
||||
bool bStopped = false;
|
||||
bool bFiltered = false;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
const std::string m_ConfigFilepath;
|
||||
const std::string m_DatabaseFilepath;
|
||||
|
||||
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 OnReleaseVolumeSlider(wxScrollEvent& event);
|
||||
void OnClickSettings(wxCommandEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// DirCtrl event handlers
|
||||
void OnClickDirCtrl(wxCommandEvent& event);
|
||||
void OnDragFromDirCtrl(wxTreeEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// TrashPane event handlers
|
||||
void OnShowTrashContextMenu(wxTreeEvent& event);
|
||||
void OnClickRestoreTrashItem(wxCommandEvent& event);
|
||||
void OnDragAndDropToTrash(wxDropFilesEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Hives panel button event handlers
|
||||
void OnDragAndDropToHives(wxDropFilesEvent& event);
|
||||
void OnClickAddHive(wxCommandEvent& event);
|
||||
void OnClickRemoveHive(wxCommandEvent& event);
|
||||
void OnShowHivesContextMenu(wxDataViewEvent& event);
|
||||
void OnHiveStartEditing(wxDataViewEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// SearchCtrl event handlers
|
||||
void OnDoSearch(wxCommandEvent& event);
|
||||
void OnCancelSearch(wxCommandEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Library event handlers
|
||||
void OnClickLibrary(wxDataViewEvent& event);
|
||||
void OnDragAndDropToLibrary(wxDropFilesEvent& event);
|
||||
void OnDragFromLibrary(wxDataViewEvent& event);
|
||||
void OnShowLibraryContextMenu(wxDataViewEvent& event);
|
||||
void OnShowLibraryColumnHeaderContextMenu(wxDataViewEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// App menu items event handlers
|
||||
void OnSelectAddFile(wxCommandEvent& event);
|
||||
void OnSelectAddDirectory(wxCommandEvent& event);
|
||||
void OnSelectToggleExtension(wxCommandEvent& event);
|
||||
void OnSelectToggleMenuBar(wxCommandEvent& event);
|
||||
void OnSelectToggleStatusBar(wxCommandEvent& event);
|
||||
void OnSelectExit(wxCommandEvent& event);
|
||||
void OnSelectPreferences(wxCommandEvent& event);
|
||||
void OnSelectResetAppData(wxCommandEvent& event);
|
||||
void OnSelectAbout(wxCommandEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Statusbar event handler
|
||||
void OnResizeStatusBar(wxSizeEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Timer update event handler
|
||||
void UpdateElapsedTime(wxTimerEvent& event);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void AddSamples(wxArrayString& files);
|
||||
void OnAutoImportDir(const wxString& pathToDirectory);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
void LoadDatabase();
|
||||
void RefreshDatabase();
|
||||
void LoadConfigFile();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Getters
|
||||
FileInfo GetFilenamePathAndExtension(const wxString& selected,
|
||||
bool checkExtension = true, bool doGetFilename = true) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Directory watchers
|
||||
bool CreateWatcherIfNecessary();
|
||||
void CreateWatcher();
|
||||
|
||||
// wxString TagLibTowx(const TagLib::String& in);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Call after frame creation
|
||||
void SetAfterFrameCreate();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
friend class App;
|
||||
};
|
||||
|
|
@ -1,405 +0,0 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include <wx/log.h>
|
||||
#include <wx/stdpaths.h>
|
||||
#include <wx/filename.h>
|
||||
|
||||
#include <yaml-cpp/emittermanip.h>
|
||||
#include <yaml-cpp/node/parse.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)
|
||||
{
|
||||
wxLogDebug("Genrating configuration file..");
|
||||
|
||||
m_Emitter << YAML::Comment("This is the configuration file for SampleHive,"
|
||||
"feel free to edit the file as needed");
|
||||
m_Emitter << YAML::Newline;
|
||||
|
||||
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 << "Collection";
|
||||
m_Emitter << YAML::BeginMap;
|
||||
m_Emitter << YAML::Key << "AutoImport" << YAML::Value << false;
|
||||
m_Emitter << YAML::Key << "Directory" << YAML::Value << dir;
|
||||
m_Emitter << YAML::Key << "ShowFileExtension" << YAML::Value << true;
|
||||
m_Emitter << YAML::EndMap << YAML::Newline;
|
||||
|
||||
m_Emitter << YAML::EndMap;
|
||||
|
||||
std::ofstream ofstrm(m_Filepath);
|
||||
ofstrm << m_Emitter.c_str();
|
||||
|
||||
wxLogDebug("Generated %s successfully!", m_Filepath);
|
||||
}
|
||||
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::LoadFile(m_Filepath);
|
||||
|
||||
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("Window 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::LoadFile(m_Filepath);
|
||||
|
||||
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("Autoplay: %s, Loop: %s, Muted: %s",
|
||||
autoplay ? "enabled" : "disabled",
|
||||
loop ? "enabled" : "disabled",
|
||||
muted ? "muted" : "unmuted");
|
||||
|
||||
return control;
|
||||
}
|
||||
|
||||
void Serializer::SerializeDisplaySettings(wxFont& font)
|
||||
{
|
||||
YAML::Emitter out;
|
||||
|
||||
std::string font_face = font.GetFaceName().ToStdString();
|
||||
int font_size = font.GetPointSize();
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(m_Filepath);
|
||||
|
||||
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::LoadFile(m_Filepath);
|
||||
|
||||
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
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(m_Filepath);
|
||||
|
||||
if (auto autoImportInfo = config["Collection"])
|
||||
{
|
||||
autoImportInfo["AutoImport"] = auto_import;
|
||||
autoImportInfo["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::LoadFile(m_Filepath);
|
||||
|
||||
if (auto autoImportInfo = config["Collection"])
|
||||
{
|
||||
auto_import = autoImportInfo["AutoImport"].as<bool>();
|
||||
dir = autoImportInfo["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::SerializeShowFileExtensionSetting(wxCheckBox& checkBox)
|
||||
{
|
||||
YAML::Emitter out;
|
||||
|
||||
bool show_extension = checkBox.GetValue();
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(m_Filepath);
|
||||
|
||||
if (auto fileExtensionInfo = config["Collection"])
|
||||
{
|
||||
fileExtensionInfo["ShowFileExtension"] = show_extension;
|
||||
|
||||
out << config;
|
||||
|
||||
wxLogDebug("Changing show file extension value.");
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool Serializer::DeserializeShowFileExtensionSetting() const
|
||||
{
|
||||
bool show_extension = false;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(m_Filepath);
|
||||
|
||||
if (auto fileExtensionInfo = config["Collection"])
|
||||
{
|
||||
show_extension = fileExtensionInfo["ShowFileExtension"].as<bool>();
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogDebug("Error! Cannot fetch import dir values.");
|
||||
}
|
||||
}
|
||||
catch(const YAML::ParserException& ex)
|
||||
{
|
||||
std::cout << ex.what() << std::endl;
|
||||
}
|
||||
|
||||
return show_extension;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Show file extension
|
||||
void SerializeShowFileExtensionSetting(wxCheckBox& checkBox);
|
||||
bool DeserializeShowFileExtensionSetting() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Favorite samples
|
||||
void SerializeDataViewTreeCtrlItems(wxTreeCtrl& tree, wxTreeItemId& item);
|
||||
bool DeserializeDataViewTreeCtrlItems(YAML::Emitter& out, wxDataViewItem item) const;
|
||||
};
|
||||
|
|
@ -1,429 +0,0 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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(const std::string& configFilepath, const std::string& databaseFilepath)
|
||||
: m_ConfigFilepath(configFilepath), m_DatabaseFilepath(databaseFilepath)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Settings::Settings(wxWindow* window, const std::string& configFilepath, const 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(wxHORIZONTAL);
|
||||
m_ShowFileExtensionSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
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_ShowFileExtensionCheck = new wxCheckBox(m_CollectionSettingPanel, SD_ShowFileExtension, "Show file extension", wxDefaultPosition, wxDefaultSize, 0);
|
||||
|
||||
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_CHECKBOX, &Settings::OnCheckShowFileExtension, this, SD_ShowFileExtension);
|
||||
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 | wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT, 2);
|
||||
m_CollectionImportDirSizer->Add(m_ImportDirLocation, 1, wxALL | wxALIGN_CENTER_VERTICAL, 2);
|
||||
m_CollectionImportDirSizer->Add(m_BrowseAutoImportDirButton, 0, wxALL | wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT, 2);
|
||||
|
||||
m_ShowFileExtensionSizer->Add(m_ShowFileExtensionCheck, 0, wxALL | wxALIGN_LEFT, 2);
|
||||
|
||||
m_CollectionTopSizer->Add(m_CollectionImportDirSizer, 0, wxALL | wxEXPAND, 2);
|
||||
m_CollectionTopSizer->Add(m_ShowFileExtensionSizer, 0, 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::OnCheckShowFileExtension(wxCommandEvent& event)
|
||||
{
|
||||
Serializer serialize(m_ConfigFilepath);
|
||||
|
||||
if (!m_ShowFileExtensionCheck->GetValue())
|
||||
{
|
||||
bShowExtension = false;
|
||||
serialize.SerializeShowFileExtensionSetting(*m_ShowFileExtensionCheck);
|
||||
}
|
||||
else
|
||||
{
|
||||
bShowExtension = true;
|
||||
serialize.SerializeShowFileExtensionSetting(*m_ShowFileExtensionCheck);
|
||||
}
|
||||
}
|
||||
|
||||
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:
|
||||
{
|
||||
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();
|
||||
|
||||
bAutoImport = serializer.DeserializeAutoImportSettings().auto_import;
|
||||
wxString location = serializer.DeserializeAutoImportSettings().import_dir;
|
||||
bShowExtension = serializer.DeserializeShowFileExtensionSetting();
|
||||
|
||||
m_AutoImportCheck->SetValue(bAutoImport);
|
||||
m_ImportDirLocation->SetValue(location);
|
||||
m_ShowFileExtensionCheck->SetValue(bShowExtension);
|
||||
|
||||
if (bAutoImport)
|
||||
{
|
||||
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" )
|
||||
{
|
||||
m_Window->SetFont(sys_font);
|
||||
this->SetFont(sys_font);
|
||||
|
||||
serializer.SerializeDisplaySettings(sys_font);
|
||||
}
|
||||
else
|
||||
{
|
||||
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(){}
|
||||
|
|
@ -1,319 +0,0 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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, const std::string& dbPath, const std::string& filename, wxInfoBar& info_bar)
|
||||
: wxDialog(window, wxID_ANY, "Edit tags", wxDefaultPosition,
|
||||
wxSize(640, 360), wxDEFAULT_DIALOG_STYLE | wxSTAY_ON_TOP),
|
||||
m_Window(window), m_DatabaseFilepath(dbPath), 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_StaticEditTagSizer, 1, wxALL | wxEXPAND, 2);
|
||||
m_MainSizer->Add(m_StaticSampleTypeSizer, 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();
|
||||
|
||||
std::string sampleType = db.GetSampleType(m_DatabaseFilepath, m_Filename);
|
||||
|
||||
std::string filename = wxString(m_Filename).AfterLast('/').BeforeLast('.').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());
|
||||
|
||||
db.UpdateSamplePack(m_DatabaseFilepath, m_Filename, artist.ToStdString());
|
||||
|
||||
wxLogDebug("SAMPLE FILENAME HERE: %s", m_Filename);
|
||||
|
||||
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(m_DatabaseFilepath, filename, type.ToStdString());
|
||||
|
||||
info_msg = wxString::Format("Successfully changed type tag to %s", type);
|
||||
}
|
||||
break;
|
||||
case wxID_NO:
|
||||
break;
|
||||
default:
|
||||
info_msg = "Error, cannot change tag!";
|
||||
}
|
||||
|
||||
m_InfoBar.ShowMessage(info_msg, wxICON_INFORMATION);
|
||||
}
|
||||
|
||||
TagEditor::~TagEditor()
|
||||
{
|
||||
|
||||
}
|
||||
144
src/Tags.cpp
|
|
@ -1,144 +0,0 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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,124 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <wx/defs.h>
|
||||
|
||||
namespace SampleHive { namespace ID {
|
||||
|
||||
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_LoopABButton,
|
||||
BC_Mute,
|
||||
BC_Autoplay,
|
||||
BC_Volume,
|
||||
BC_SamplePosition,
|
||||
BC_Hives,
|
||||
BC_DirCtrl,
|
||||
BC_Library,
|
||||
BC_Search,
|
||||
BC_MediaCtrl,
|
||||
BC_Trash,
|
||||
BC_RestoreTrashedItem,
|
||||
BC_HiveAdd,
|
||||
BC_HiveRemove,
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Setting dialog controls
|
||||
SD_BrowseConfigDir,
|
||||
SD_BrowseDatabaseDir,
|
||||
SD_AutoImport,
|
||||
SD_FollowSymLinks,
|
||||
SD_RecursiveImport,
|
||||
SD_ShowFileExtension,
|
||||
SD_DoubleClickToPlay,
|
||||
SD_BrowseAutoImportDir,
|
||||
SD_FontType,
|
||||
SD_FontSize,
|
||||
SD_FontBrowseButton,
|
||||
SD_WaveformColourPickerCtrl,
|
||||
SD_ShowSplash,
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// App Menu items
|
||||
MN_AddFile,
|
||||
MN_AddDirectory,
|
||||
MN_ToggleExtension,
|
||||
MN_ToggleMenuBar,
|
||||
MN_ToggleStatusBar,
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Library Menu items
|
||||
MN_FavoriteSample,
|
||||
MN_DeleteSample,
|
||||
MN_TrashSample,
|
||||
MN_EditTagSample,
|
||||
MN_OpenFile,
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Library Column Header Menu items
|
||||
MN_ColumnFavorite,
|
||||
MN_ColumnFilename,
|
||||
MN_ColumnSamplePack,
|
||||
MN_ColumnType,
|
||||
MN_ColumnChannels,
|
||||
MN_ColumnBPM,
|
||||
MN_ColumnLength,
|
||||
MN_ColumnSampleRate,
|
||||
MN_ColumnBitrate,
|
||||
MN_ColumnPath,
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Hives Menu items
|
||||
MN_RenameHive,
|
||||
MN_DeleteHive,
|
||||
MN_RemoveSample,
|
||||
MN_FilterLibrary,
|
||||
MN_ShowInLibrary,
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Trash Menu items
|
||||
MN_DeleteTrash,
|
||||
MN_RestoreTrashedItem,
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Edit tags dialog controls
|
||||
ET_TitleCheck,
|
||||
ET_ArtistCheck,
|
||||
ET_AlbumCheck,
|
||||
ET_GenreCheck,
|
||||
ET_CommentsCheck,
|
||||
ET_TypeCheck,
|
||||
ET_CustomTag,
|
||||
};
|
||||
|
||||
}}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Utility/Event.hpp"
|
||||
|
||||
namespace SampleHive
|
||||
{
|
||||
cLoopPointsEvent::cLoopPointsEvent(wxEventType eventType, int winId)
|
||||
: wxCommandEvent(eventType, winId)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
cLoopPointsEvent::~cLoopPointsEvent()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
wxDEFINE_EVENT(SH_EVT_LOOP_POINTS_UPDATED, cLoopPointsEvent);
|
||||
wxDEFINE_EVENT(SH_EVT_LOOP_POINTS_CLEAR, cLoopPointsEvent);
|
||||
wxDEFINE_EVENT(SH_EVT_LOOP_AB_BUTTON_VALUE_CHANGE, cLoopPointsEvent);
|
||||
|
||||
// MediaEvent::MediaEvent(wxEventType eventType, int winId)
|
||||
// : wxCommandEvent(eventType, winId)
|
||||
// {
|
||||
|
||||
// }
|
||||
|
||||
// MediaEvent::~MediaEvent()
|
||||
// {
|
||||
|
||||
// }
|
||||
|
||||
// wxDEFINE_EVENT(SH_EVT_MEDIA_STATUS_UPDATED, MediaEvent);
|
||||
|
||||
cStatusBarStatusEvent::cStatusBarStatusEvent(wxEventType eventType, int winId)
|
||||
: wxCommandEvent(eventType, winId)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
cStatusBarStatusEvent::~cStatusBarStatusEvent()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
wxDEFINE_EVENT(SH_EVT_STATUSBAR_STATUS_PUSH, cStatusBarStatusEvent);
|
||||
wxDEFINE_EVENT(SH_EVT_STATUSBAR_STATUS_POP, cStatusBarStatusEvent);
|
||||
wxDEFINE_EVENT(SH_EVT_STATUSBAR_STATUS_SET, cStatusBarStatusEvent);
|
||||
|
||||
cInfoBarMessageEvent::cInfoBarMessageEvent(wxEventType eventType, int winId)
|
||||
: wxCommandEvent(eventType, winId)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
cInfoBarMessageEvent::~cInfoBarMessageEvent()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
wxDEFINE_EVENT(SH_EVT_INFOBAR_MESSAGE_SHOW, cInfoBarMessageEvent);
|
||||
|
||||
cTimerEvent::cTimerEvent(wxEventType eventType, int winId)
|
||||
: wxCommandEvent(eventType, winId)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
cTimerEvent::~cTimerEvent()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
wxDEFINE_EVENT(SH_EVT_TIMER_STOP, cTimerEvent);
|
||||
|
||||
cCallFunctionEvent::cCallFunctionEvent(wxEventType eventType, int winId)
|
||||
: wxCommandEvent(eventType, winId)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
cCallFunctionEvent::~cCallFunctionEvent()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
wxDEFINE_EVENT(SH_EVT_CALL_FUNC_PLAY, cCallFunctionEvent);
|
||||
|
||||
cWaveformUpdateEvent::cWaveformUpdateEvent(wxEventType eventType, int winId)
|
||||
: wxCommandEvent(eventType, winId)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
cWaveformUpdateEvent::~cWaveformUpdateEvent()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
wxDEFINE_EVENT(SH_EVT_UPDATE_WAVEFORM, cWaveformUpdateEvent);
|
||||
}
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include <wx/event.h>
|
||||
|
||||
namespace SampleHive
|
||||
{
|
||||
class cLoopPointsEvent : public wxCommandEvent
|
||||
{
|
||||
public:
|
||||
cLoopPointsEvent(wxEventType eventType, int winId);
|
||||
~cLoopPointsEvent();
|
||||
|
||||
public:
|
||||
virtual wxEvent* Clone() const { return new cLoopPointsEvent(*this); }
|
||||
|
||||
public:
|
||||
std::pair<double, double> GetLoopPoints() const { return { m_LoopA, m_LoopB }; };
|
||||
void SetLoopPoints(std::pair<double&, double&> loopPoints)
|
||||
{ m_LoopA = loopPoints.first; m_LoopB = loopPoints.second; };
|
||||
|
||||
private:
|
||||
double m_LoopA, m_LoopB;
|
||||
};
|
||||
|
||||
wxDECLARE_EVENT(SH_EVT_LOOP_POINTS_UPDATED, cLoopPointsEvent);
|
||||
wxDECLARE_EVENT(SH_EVT_LOOP_POINTS_CLEAR, cLoopPointsEvent);
|
||||
wxDECLARE_EVENT(SH_EVT_LOOP_AB_BUTTON_VALUE_CHANGE, cLoopPointsEvent);
|
||||
|
||||
// class cMediaEvent : public wxCommandEvent
|
||||
// {
|
||||
// public:
|
||||
// cMediaEvent(wxEventType eventType, int winId);
|
||||
// ~cMediaEvent();
|
||||
|
||||
// public:
|
||||
// virtual wxEvent* Clone() const { return new cMediaEvent(*this); }
|
||||
|
||||
// public:
|
||||
// void SetPath(const wxString& path) { m_Path = path; }
|
||||
// wxString GetPath() const { return m_Path; }
|
||||
|
||||
// private:
|
||||
// wxString m_Path;
|
||||
// };
|
||||
|
||||
// wxDECLARE_EVENT(SH_EVT_MEDIA_STATUS_UPDATED, cMediaEvent);
|
||||
|
||||
class cStatusBarStatusEvent : public wxCommandEvent
|
||||
{
|
||||
public:
|
||||
cStatusBarStatusEvent(wxEventType eventType, int winId);
|
||||
~cStatusBarStatusEvent();
|
||||
|
||||
public:
|
||||
virtual wxEvent* Clone() const { return new cStatusBarStatusEvent(*this); }
|
||||
|
||||
public:
|
||||
std::pair<wxString, int> GetPushMessageAndSection() const { return { m_Msg, m_PushSection }; }
|
||||
void SetPushMessageAndSection(std::pair<const wxString&, int> status)
|
||||
{ m_Msg = status.first; m_PushSection = status.second; }
|
||||
|
||||
std::pair<wxString, int> GetStatusTextAndSection() const { return { m_Text, m_SetSection }; }
|
||||
void SetStatusTextAndSection(std::pair<const wxString&, int> status)
|
||||
{ m_Text = status.first, m_SetSection = status.second; }
|
||||
|
||||
int GetPopMessageSection() const { return m_PopSection; }
|
||||
void SetPopMessageSection(int section) { m_PopSection = section; }
|
||||
|
||||
private:
|
||||
wxString m_Msg, m_Text;
|
||||
int m_PushSection, m_PopSection, m_SetSection;
|
||||
};
|
||||
|
||||
wxDECLARE_EVENT(SH_EVT_STATUSBAR_STATUS_PUSH, cStatusBarStatusEvent);
|
||||
wxDECLARE_EVENT(SH_EVT_STATUSBAR_STATUS_POP, cStatusBarStatusEvent);
|
||||
wxDECLARE_EVENT(SH_EVT_STATUSBAR_STATUS_SET, cStatusBarStatusEvent);
|
||||
|
||||
class cInfoBarMessageEvent : public wxCommandEvent
|
||||
{
|
||||
public:
|
||||
cInfoBarMessageEvent(wxEventType eventType, int winId);
|
||||
~cInfoBarMessageEvent();
|
||||
|
||||
public:
|
||||
virtual wxEvent* Clone() const { return new cInfoBarMessageEvent(*this); }
|
||||
|
||||
public:
|
||||
std::pair<wxString, int> GetInfoBarMessage() const { return { m_Msg, m_Mode }; }
|
||||
void SetInfoBarMessage(std::pair<const wxString&, int> info)
|
||||
{ m_Msg = info.first; m_Mode = info.second; }
|
||||
|
||||
private:
|
||||
wxString m_Msg;
|
||||
int m_Mode;
|
||||
};
|
||||
|
||||
wxDECLARE_EVENT(SH_EVT_INFOBAR_MESSAGE_SHOW, cInfoBarMessageEvent);
|
||||
|
||||
class cTimerEvent : public wxCommandEvent
|
||||
{
|
||||
public:
|
||||
cTimerEvent(wxEventType eventType, int winId);
|
||||
~cTimerEvent();
|
||||
|
||||
public:
|
||||
virtual wxEvent* Clone() const { return new cTimerEvent(*this); }
|
||||
};
|
||||
|
||||
wxDECLARE_EVENT(SH_EVT_TIMER_STOP, cTimerEvent);
|
||||
|
||||
class cCallFunctionEvent : public wxCommandEvent
|
||||
{
|
||||
public:
|
||||
cCallFunctionEvent(wxEventType eventType, int winId);
|
||||
~cCallFunctionEvent();
|
||||
|
||||
public:
|
||||
virtual wxEvent* Clone() const { return new cCallFunctionEvent(*this); }
|
||||
|
||||
public:
|
||||
wxString GetSlection() const { return m_Selection; }
|
||||
bool GetAutoplayValue() const { return m_bCheckAutoplay; }
|
||||
void SetSelection(const wxString& selection) { m_Selection = selection; }
|
||||
void SetAutoplayValue(bool autoplay) { m_bCheckAutoplay = autoplay; }
|
||||
|
||||
private:
|
||||
wxString m_Selection;
|
||||
bool m_bCheckAutoplay;
|
||||
};
|
||||
|
||||
wxDECLARE_EVENT(SH_EVT_CALL_FUNC_PLAY, cCallFunctionEvent);
|
||||
|
||||
class cWaveformUpdateEvent : public wxCommandEvent
|
||||
{
|
||||
public:
|
||||
cWaveformUpdateEvent(wxEventType eventType, int winId);
|
||||
~cWaveformUpdateEvent();
|
||||
|
||||
public:
|
||||
virtual wxEvent* Clone() const { return new cWaveformUpdateEvent(*this); }
|
||||
};
|
||||
|
||||
wxDECLARE_EVENT(SH_EVT_UPDATE_WAVEFORM, cWaveformUpdateEvent);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "wx/dataview.h"
|
||||
#include "wx/string.h"
|
||||
#include "wx/treectrl.h"
|
||||
#include "wx/treebase.h"
|
||||
#include "wx/variant.h"
|
||||
#include "wx/vector.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace SampleHive {
|
||||
|
||||
class cHiveData
|
||||
{
|
||||
private:
|
||||
cHiveData() = default;
|
||||
|
||||
public:
|
||||
cHiveData(const cHiveData&) = delete;
|
||||
cHiveData& operator=(const cHiveData) = delete;
|
||||
|
||||
public:
|
||||
static cHiveData& Get()
|
||||
{
|
||||
static cHiveData s_HiveData;
|
||||
return s_HiveData;
|
||||
}
|
||||
|
||||
public:
|
||||
// ===============================================================
|
||||
// HivesPanel functions
|
||||
void InitHiveData(wxDataViewListCtrl& listCtrl, wxDataViewTreeCtrl& hives, wxDataViewItem favoriteHive,
|
||||
wxTreeCtrl& trash, wxTreeItemId trashRoot)
|
||||
{
|
||||
m_pListCtrl = &listCtrl;
|
||||
m_FavoriteHive = favoriteHive;
|
||||
m_pHives = &hives;
|
||||
m_TrashRoot = trashRoot;
|
||||
m_pTrash = &trash;
|
||||
}
|
||||
|
||||
inline wxDataViewTreeCtrl& GetHivesObj() { return *m_pHives; }
|
||||
inline wxDataViewItem& GetFavoritesHive() { return m_FavoriteHive; }
|
||||
|
||||
wxString GetHiveItemText(bool ofFavHive = false, wxDataViewItem hive = wxDataViewItem(0))
|
||||
{
|
||||
wxString item_text;
|
||||
|
||||
if (ofFavHive)
|
||||
item_text = m_pHives->GetItemText(m_FavoriteHive);
|
||||
else
|
||||
item_text = m_pHives->GetItemText(hive);
|
||||
|
||||
return item_text;
|
||||
}
|
||||
|
||||
inline wxDataViewItem GetHiveItemSelection() { return m_pHives->GetSelection(); }
|
||||
inline bool IsHiveItemContainer(wxDataViewItem& hiveItem) { return m_pHives->IsContainer(hiveItem); }
|
||||
inline int GetHiveChildCount(wxDataViewItem& root) { return m_pHives->GetChildCount(root); }
|
||||
inline wxDataViewItem GetHiveNthChild(wxDataViewItem& root, int pos) { return m_pHives->GetNthChild(root, pos); }
|
||||
inline void HiveAppendItem(wxDataViewItem& hiveItem, wxString name) { m_pHives->AppendItem(hiveItem, name); }
|
||||
inline void HiveDeleteItem(wxDataViewItem& hiveItem) { m_pHives->DeleteItem(hiveItem); }
|
||||
|
||||
// ===============================================================
|
||||
// TrashPanel functions
|
||||
inline wxTreeCtrl& GetTrashObj() { return *m_pTrash; }
|
||||
inline wxTreeItemId& GetTrashRoot() { return m_TrashRoot; }
|
||||
inline void TrashAppendItem(const wxTreeItemId& parent, const wxString& text) { m_pTrash->AppendItem(parent, text); }
|
||||
|
||||
// ===============================================================
|
||||
// ListCtrl functions
|
||||
inline wxDataViewListCtrl& GetListCtrlObj() { return *m_pListCtrl; }
|
||||
inline int GetListCtrlSelections(wxDataViewItemArray& items) { return m_pListCtrl->GetSelections(items); }
|
||||
inline int GetListCtrlRowFromItem(wxDataViewItemArray& items, int index) { return m_pListCtrl->ItemToRow(items[index]); }
|
||||
inline int GetListCtrlSelectedRow() { return m_pListCtrl->GetSelectedRow(); }
|
||||
inline wxDataViewItem GetListCtrlItemFromRow(int row) { return m_pListCtrl->RowToItem(row); }
|
||||
inline wxString GetListCtrlTextValue(unsigned int row, unsigned int col) { return m_pListCtrl->GetTextValue(row, col); }
|
||||
inline int GetListCtrlItemCount() { return m_pListCtrl->GetItemCount(); }
|
||||
inline void ListCtrlAppendItem(const wxVector<wxVariant>& values) { m_pListCtrl->AppendItem(values); }
|
||||
inline void ListCtrlSetVariant(const wxVariant& variant, unsigned int row, unsigned int col)
|
||||
{ m_pListCtrl->SetValue(variant, row, col); }
|
||||
inline void ListCtrlUnselectAllItems() { m_pListCtrl->UnselectAll(); }
|
||||
inline void ListCtrlSelectRow(int row) { m_pListCtrl->SelectRow(row); }
|
||||
inline void ListCtrlEnsureVisible(const wxDataViewItem& item) { m_pListCtrl->EnsureVisible(item); }
|
||||
inline void ListCtrlDeleteItem(unsigned int row) { m_pListCtrl->DeleteItem(row); }
|
||||
inline void ListCtrlDeleteAllItems() { m_pListCtrl->DeleteAllItems(); }
|
||||
|
||||
private:
|
||||
wxDataViewListCtrl* m_pListCtrl = nullptr;
|
||||
wxDataViewItem m_FavoriteHive;
|
||||
wxDataViewTreeCtrl* m_pHives = nullptr;
|
||||
wxTreeCtrl* m_pTrash = nullptr;
|
||||
wxTreeItemId m_TrashRoot;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Log.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "spdlog/sinks/stdout_color_sinks.h"
|
||||
|
||||
namespace SampleHive {
|
||||
|
||||
std::shared_ptr<spdlog::logger> cLog::s_pLogger;
|
||||
|
||||
void cLog::InitLogger(const std::string& logger)
|
||||
{
|
||||
spdlog::set_pattern("%^[%-T] [%-n] [%l]: %v %@%$");
|
||||
|
||||
try
|
||||
{
|
||||
s_pLogger = spdlog::stdout_color_mt(logger);
|
||||
s_pLogger->set_level(spdlog::level::trace);
|
||||
}
|
||||
catch (const spdlog::spdlog_ex& ex)
|
||||
{
|
||||
std::cout << "Logger initialization failed: " << ex.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <SampleHiveConfig.hpp>
|
||||
|
||||
#ifdef SH_BUILD_DEBUG
|
||||
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE
|
||||
#else
|
||||
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_OFF
|
||||
#endif
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
namespace SampleHive {
|
||||
|
||||
class cLog
|
||||
{
|
||||
public:
|
||||
static void InitLogger(const std::string& logger);
|
||||
|
||||
public:
|
||||
inline static std::shared_ptr<spdlog::logger>& GetLogger() { return s_pLogger; }
|
||||
|
||||
private:
|
||||
static std::shared_ptr<spdlog::logger> s_pLogger;
|
||||
};
|
||||
|
||||
// Log macros
|
||||
#define SH_LOG_TRACE(...) SPDLOG_LOGGER_TRACE(::SampleHive::cLog::GetLogger(), __VA_ARGS__)
|
||||
#define SH_LOG_INFO(...) SPDLOG_LOGGER_INFO(::SampleHive::cLog::GetLogger(), __VA_ARGS__)
|
||||
#define SH_LOG_WARN(...) SPDLOG_LOGGER_WARN(::SampleHive::cLog::GetLogger(), __VA_ARGS__)
|
||||
#define SH_LOG_DEBUG(...) SPDLOG_LOGGER_DEBUG(::SampleHive::cLog::GetLogger(), __VA_ARGS__)
|
||||
#define SH_LOG_ERROR(...) SPDLOG_LOGGER_ERROR(::SampleHive::cLog::GetLogger(), __VA_ARGS__)
|
||||
#define SH_LOG_CRITICAL(...) SPDLOG_LOGGER_CRITICAL(::SampleHive::cLog::GetLogger(), __VA_ARGS__)
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SampleHiveConfig.hpp"
|
||||
|
||||
namespace SampleHive {
|
||||
|
||||
// Path to all the assets
|
||||
#define ICON_HIVE_16px SAMPLEHIVE_DATADIR "/icons/icon-hive_16x16.png"
|
||||
#define ICON_HIVE_24px SAMPLEHIVE_DATADIR "/icons/icon-hive_24x24.png"
|
||||
#define ICON_HIVE_32px SAMPLEHIVE_DATADIR "/icons/icon-hive_32x32.png"
|
||||
#define ICON_HIVE_64px SAMPLEHIVE_DATADIR "/icons/icon-hive_64x64.png"
|
||||
#define ICON_HIVE_128px SAMPLEHIVE_DATADIR "/icons/icon-hive_128x128.png"
|
||||
#define ICON_HIVE_256px SAMPLEHIVE_DATADIR "/icons/icon-hive_256x256.png"
|
||||
#define ICON_STAR_FILLED_16px SAMPLEHIVE_DATADIR "/icons/icon-star_filled_16x16.png"
|
||||
#define ICON_STAR_EMPTY_16px SAMPLEHIVE_DATADIR "/icons/icon-star_empty_16x16.png"
|
||||
#define ICON_PLAY_DARK_16px SAMPLEHIVE_DATADIR "/icons/icon-play-dark_16x16.png"
|
||||
#define ICON_STOP_DARK_16px SAMPLEHIVE_DATADIR "/icons/icon-stop-dark_16x16.png"
|
||||
#define ICON_AB_DARK_16px SAMPLEHIVE_DATADIR "/icons/icon-ab-dark_16x16.png"
|
||||
#define ICON_LOOP_DARK_16px SAMPLEHIVE_DATADIR "/icons/icon-loop-dark_16x16.png"
|
||||
#define ICON_MUTE_DARK_16px SAMPLEHIVE_DATADIR "/icons/icon-mute-dark_16x16.png"
|
||||
#define ICON_PLAY_LIGHT_16px SAMPLEHIVE_DATADIR "/icons/icon-play-light_16x16.png"
|
||||
#define ICON_STOP_LIGHT_16px SAMPLEHIVE_DATADIR "/icons/icon-stop-light_16x16.png"
|
||||
#define ICON_AB_LIGHT_16px SAMPLEHIVE_DATADIR "/icons/icon-ab-light_16x16.png"
|
||||
#define ICON_LOOP_LIGHT_16px SAMPLEHIVE_DATADIR "/icons/icon-loop-light_16x16.png"
|
||||
#define ICON_MUTE_LIGHT_16px SAMPLEHIVE_DATADIR "/icons/icon-mute-light_16x16.png"
|
||||
#define SPLASH_LOGO SAMPLEHIVE_DATADIR "/logo/logo-samplehive_768x432.png"
|
||||
|
||||
// Path to useful directories and files
|
||||
#define USER_HOME_DIR wxGetUserHome()
|
||||
#define APP_CONFIG_DIR USER_HOME_DIR + "/.config/SampleHive"
|
||||
#define APP_DATA_DIR USER_HOME_DIR + "/.local/share/SampleHive"
|
||||
#define CONFIG_FILEPATH APP_CONFIG_DIR + "/config.yaml"
|
||||
#define DATABASE_FILEPATH APP_DATA_DIR "/sample.hive"
|
||||
|
||||
}
|
||||
|
|
@ -26,18 +26,20 @@
|
|||
* @copyright GNU GPL v3
|
||||
*/
|
||||
|
||||
#include "Sample.hpp"
|
||||
#include "Utility/Sample.hpp"
|
||||
|
||||
///Default Constructor, Creates an empty sample profile
|
||||
Sample::Sample(){}
|
||||
Sample::Sample()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
///Overloaded Constructor, Creates a sample profile with supplied data. @see Set()
|
||||
Sample::Sample(int favorite, const std::string& filename, const std::string& fileExtension,
|
||||
const std::string& samplePack, const std::string& type, int channels, int length,
|
||||
int sampleRate, int bitrate, const std::string& path, int trashed)
|
||||
const std::string& samplePack, const std::string& type, int channels, int bpm,
|
||||
int length, int sampleRate, int bitrate, const std::string& path, int trashed)
|
||||
{
|
||||
Set(favorite, filename, fileExtension, samplePack, type,
|
||||
channels, length, sampleRate, bitrate, path, trashed);
|
||||
Set(favorite, filename, fileExtension, samplePack, type, channels, bpm, length, sampleRate, bitrate, path, trashed);
|
||||
}
|
||||
|
||||
///Clears all sample data
|
||||
|
|
@ -45,6 +47,7 @@ void Sample::Clear()
|
|||
{
|
||||
m_Favorite = 0;
|
||||
m_Channels = 0;
|
||||
m_BPM = 0;
|
||||
m_Length = 0;
|
||||
m_SampleRate = 0;
|
||||
m_Bitrate = 0;
|
||||
|
|
@ -56,21 +59,9 @@ void Sample::Clear()
|
|||
m_Path = "";
|
||||
}
|
||||
|
||||
// int Sample::GetFavorite() { return m_Favorite; }
|
||||
// int Sample::GetChannels() { return m_Channels; }
|
||||
// int Sample::GetLength() { return m_Length; }
|
||||
// int Sample::GetSampleRate() { return m_SampleRate; }
|
||||
// int Sample::GetBitrate() { return m_Bitrate; }
|
||||
// int Sample::GetTrashed () { return m_Trashed; }
|
||||
// std::string Sample::GetFilename() { return m_Filename; }
|
||||
// std::string Sample::GetFileExtension() { return m_FileExtension; }
|
||||
// std::string Sample::GetSamplePack() { return m_SamplePack; }
|
||||
// std::string Sample::GetType() { return m_Type; }
|
||||
// std::string Sample::GetPath() { return m_Path; }
|
||||
|
||||
void Sample::Set(int favorite, const std::string& filename, const std::string& fileExtension,
|
||||
const std::string& samplePack, const std::string& type, int channels, int length,
|
||||
int sampleRate, int bitrate, const std::string& path, int trashed)
|
||||
const std::string& samplePack, const std::string& type, int channels, int bpm,
|
||||
int length, int sampleRate, int bitrate, const std::string& path, int trashed)
|
||||
{
|
||||
m_Favorite = favorite;
|
||||
m_Filename = filename;
|
||||
|
|
@ -78,21 +69,10 @@ void Sample::Set(int favorite, const std::string& filename, const std::string& f
|
|||
m_SamplePack = samplePack;
|
||||
m_Type = type;
|
||||
m_Channels = channels;
|
||||
m_BPM = bpm;
|
||||
m_Length = length;
|
||||
m_SampleRate = sampleRate;
|
||||
m_Bitrate = bitrate;
|
||||
m_Path = path;
|
||||
m_Trashed = trashed;
|
||||
}
|
||||
|
||||
// void Sample::SetFavorite(int favorite) { m_Favorite = favorite; }
|
||||
// void Sample::SetChannels(int channels) { m_Channels = channels; }
|
||||
// void Sample::SetLength(int length) { m_Length = length; }
|
||||
// void Sample::SetSampleRate(int sampleRate) { m_SampleRate = sampleRate; }
|
||||
// void Sample::SetBitrate(int bitrate) { m_Bitrate = bitrate; }
|
||||
// void Sample::SetTrashed (int trashed) { m_Trashed = trashed; }
|
||||
// void Sample::SetFilename(std::string filename) { m_Filename = filename; }
|
||||
// void Sample::SetFileExtension(std::string fileExtension) { m_FileExtension = fileExtension; }
|
||||
// void Sample::SetSamplePack(std::string samplePack) { m_SamplePack = samplePack; }
|
||||
// void Sample::SetType(std::string type) { m_Type = type; }
|
||||
// void Sample::SetPath(std::string path) { m_Path = path; }
|
||||
|
|
@ -26,8 +26,7 @@
|
|||
* @copyright GNU GPL v3
|
||||
*/
|
||||
|
||||
#ifndef _SAMPLE_HPP__
|
||||
#define _SAMPLE_HPP__
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
|
|
@ -40,15 +39,15 @@ class Sample
|
|||
{
|
||||
public:
|
||||
Sample();
|
||||
|
||||
Sample(int favorite, const std::string& filename, const std::string& fileExtension,
|
||||
const std::string& samplePack, const std::string& type, int channels, int length,
|
||||
int sampleRate, int bitrate, const std::string& path, int trashed);
|
||||
const std::string& samplePack, const std::string& type, int channels, int bpm,
|
||||
int length, int sampleRate, int bitrate, const std::string& path, int trashed);
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
int m_Favorite = 0;
|
||||
int m_Channels = 0;
|
||||
int m_BPM = 0;
|
||||
int m_Length = 0;
|
||||
int m_SampleRate = 0;
|
||||
int m_Bitrate = 0;
|
||||
|
|
@ -62,20 +61,9 @@ class Sample
|
|||
public:
|
||||
// -------------------------------------------------------------------
|
||||
// Getters
|
||||
// int GetFavorite();
|
||||
// int GetChannels();
|
||||
// int GetLength();
|
||||
// int GetSampleRate();
|
||||
// int GetBitrate();
|
||||
// int GetTrashed ();
|
||||
// std::string GetFilename();
|
||||
// std::string GetFileExtension();
|
||||
// std::string GetSamplePack();
|
||||
// std::string GetType();
|
||||
// std::string GetPath();
|
||||
|
||||
int GetFavorite() const { return m_Favorite; }
|
||||
int GetChannels() const { return m_Channels; }
|
||||
int GetBPM() const { return m_BPM; }
|
||||
int GetLength() const { return m_Length; }
|
||||
int GetSampleRate() const { return m_SampleRate; }
|
||||
int GetBitrate() const { return m_Bitrate; }
|
||||
|
|
@ -86,30 +74,15 @@ class Sample
|
|||
std::string GetType() const { return m_Type; }
|
||||
std::string GetPath() const { return m_Path; }
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Clear sample data
|
||||
void Clear();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Setters
|
||||
void Set(int favorite, const std::string& filename, const std::string& fileExtension,
|
||||
const std::string& samplePack, const std::string& type, int channels, int length,
|
||||
int sampleRate, int bitrate, const std::string& path, int trashed);
|
||||
|
||||
// void SetFavorite(int favorite);
|
||||
// void SetChannels(int channels);
|
||||
// void SetLength(int length);
|
||||
// void SetSampleRate(int sampleRate);
|
||||
// void SetBitrate(int bitrate);
|
||||
// void SetTrashed(int trashed);
|
||||
// void SetFilename(std::string filename);
|
||||
// void SetFileExtension(std::string fileExtension);
|
||||
// void SetSamplePack(std::string samplePack);
|
||||
// void SetType(std::string type);
|
||||
// void SetPath(std::string path);
|
||||
const std::string& samplePack, const std::string& type, int channels, int bpm,
|
||||
int length, int sampleRate, int bitrate, const std::string& path, int trashed);
|
||||
|
||||
void SetFavorite(int favorite) { m_Favorite = favorite; }
|
||||
void SetChannels(int channels) { m_Channels = channels; }
|
||||
void SetBPM(int bpm) { m_BPM = bpm; }
|
||||
void SetLength(int length) { m_Length = length; }
|
||||
void SetSampleRate(int sampleRate) { m_SampleRate = sampleRate; }
|
||||
void SetBitrate(int bitrate) { m_Bitrate = bitrate; }
|
||||
|
|
@ -119,6 +92,8 @@ class Sample
|
|||
void SetSamplePack(const std::string& samplePack) { m_SamplePack = samplePack; }
|
||||
void SetType(const std::string& type) { m_Type = type; }
|
||||
void SetPath(const std::string& path) { m_Path = path; }
|
||||
};
|
||||
|
||||
#endif
|
||||
// -------------------------------------------------------------------
|
||||
// Clear sample data
|
||||
void Clear();
|
||||
};
|
||||
|
|
@ -0,0 +1,921 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Utility/Serialize.hpp"
|
||||
#include "Utility/Log.hpp"
|
||||
#include "Utility/Paths.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include <wx/colour.h>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/settings.h>
|
||||
|
||||
#include <yaml-cpp/emittermanip.h>
|
||||
#include <yaml-cpp/node/parse.h>
|
||||
|
||||
namespace SampleHive {
|
||||
|
||||
cSerializer::cSerializer()
|
||||
{
|
||||
std::ifstream ifstrm(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
|
||||
std::string system_font_face = font.GetFaceName().ToStdString();
|
||||
int system_font_size = font.GetPointSize();
|
||||
|
||||
wxColour colour = "#FE9647";
|
||||
|
||||
std::string dir = wxGetHomeDir().ToStdString();
|
||||
|
||||
// Initialize the logger
|
||||
// SampleHive::Log::InitLogger("Serializer");
|
||||
|
||||
if (!ifstrm)
|
||||
{
|
||||
SH_LOG_INFO("Genrating configuration file..");
|
||||
|
||||
m_Emitter << YAML::Comment("This is the configuration file for SampleHive,"
|
||||
"feel free to edit the file as needed");
|
||||
m_Emitter << YAML::Newline;
|
||||
|
||||
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::Key << "TopSplitterSashPos" << YAML::Value << 200;
|
||||
m_Emitter << YAML::Key << "BottomSplitterSashPos" << YAML::Value << 300;
|
||||
m_Emitter << YAML::Key << "ShowMenuBar" << YAML::Value << true;
|
||||
m_Emitter << YAML::Key << "ShowStatusBar" << YAML::Value << true;
|
||||
m_Emitter << YAML::EndMap << YAML::Newline;
|
||||
|
||||
m_Emitter << YAML::Newline << YAML::Key << "General";
|
||||
m_Emitter << YAML::BeginMap;
|
||||
m_Emitter << YAML::Key << "DemoMode" << YAML::Value << false;
|
||||
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::Key << "Volume" << YAML::Value << 100;
|
||||
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::Key << "Waveform";
|
||||
m_Emitter << YAML::BeginMap;
|
||||
m_Emitter << YAML::Key << "Colour" << YAML::Value << colour.GetAsString().ToStdString();
|
||||
m_Emitter << YAML::EndMap;
|
||||
m_Emitter << YAML::Key << "Splash";
|
||||
m_Emitter << YAML::BeginMap;
|
||||
m_Emitter << YAML::Key << "ShowSplashOnStartup" << YAML::Value << true;
|
||||
m_Emitter << YAML::EndMap;
|
||||
m_Emitter << YAML::EndMap << YAML::Newline;
|
||||
|
||||
m_Emitter << YAML::Newline << YAML::Key << "Collection";
|
||||
m_Emitter << YAML::BeginMap;
|
||||
m_Emitter << YAML::Key << "AutoImport" << YAML::Value << false;
|
||||
m_Emitter << YAML::Key << "Directory" << YAML::Value << dir;
|
||||
m_Emitter << YAML::Key << "FollowSymLink" << YAML::Value << false;
|
||||
m_Emitter << YAML::Key << "RecursiveImport" << YAML::Value << false;
|
||||
m_Emitter << YAML::Key << "ShowFileExtension" << YAML::Value << true;
|
||||
m_Emitter << YAML::Key << "DoubleClickToPlay" << YAML::Value << false;
|
||||
m_Emitter << YAML::EndMap << YAML::Newline;
|
||||
|
||||
m_Emitter << YAML::EndMap;
|
||||
|
||||
std::ofstream ofstrm(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
ofstrm << m_Emitter.c_str();
|
||||
|
||||
SH_LOG_INFO("Generated {} successfully!", static_cast<std::string>(CONFIG_FILEPATH));
|
||||
}
|
||||
}
|
||||
|
||||
cSerializer::~cSerializer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void cSerializer::SerializeWinSize(int w, int h)
|
||||
{
|
||||
YAML::Emitter out;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (auto win = config["Window"])
|
||||
{
|
||||
win["Width"] = w;
|
||||
win["Height"] = h;
|
||||
|
||||
out << config;
|
||||
|
||||
std::ofstream ofstrm(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
ofstrm << out.c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
SH_LOG_ERROR("Error! Cannot store window size values.");
|
||||
}
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
WindowSize cSerializer::DeserializeWinSize() const
|
||||
{
|
||||
int width = 800, height = 600;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (!config["Window"])
|
||||
{
|
||||
return { width, height };
|
||||
}
|
||||
|
||||
if (auto win = config["Window"])
|
||||
{
|
||||
height = win["Height"].as<int>();
|
||||
width = win["Width"].as<int>();
|
||||
}
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
|
||||
SH_LOG_INFO("Window size: {}, {}", width, height);
|
||||
|
||||
return { width, height };
|
||||
}
|
||||
|
||||
void cSerializer::SerializeShowMenuAndStatusBar(std::string key, bool value)
|
||||
{
|
||||
YAML::Emitter out;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (auto bar = config["Window"])
|
||||
{
|
||||
if (key == "menubar")
|
||||
bar["ShowMenuBar"] = value;
|
||||
|
||||
if (key == "statusbar")
|
||||
bar["ShowStatusBar"] = value;
|
||||
|
||||
out << config;
|
||||
|
||||
std::ofstream ofstrm(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
ofstrm << out.c_str();
|
||||
}
|
||||
else
|
||||
SH_LOG_ERROR("Error! Cannot store show bar values.");
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
bool cSerializer::DeserializeShowMenuAndStatusBar(std::string key) const
|
||||
{
|
||||
bool show = false;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (auto bar = config["Window"])
|
||||
{
|
||||
if (key == "menubar")
|
||||
show = bar["ShowMenuBar"].as<bool>();
|
||||
|
||||
if (key == "statusbar")
|
||||
show = bar["ShowStatusBar"].as<bool>();
|
||||
}
|
||||
else
|
||||
{
|
||||
SH_LOG_ERROR("Error! Cannot fetch show bar values.");
|
||||
}
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
|
||||
return show;
|
||||
}
|
||||
|
||||
void cSerializer::SerializeSplitterSashPos(std::string key, int pos)
|
||||
{
|
||||
YAML::Emitter out;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (auto sash = config["Window"])
|
||||
{
|
||||
if (key == "top")
|
||||
sash["TopSplitterSashPos"] = pos;
|
||||
|
||||
if (key == "bottom")
|
||||
sash["BottomSplitterSashPos"] = pos;
|
||||
|
||||
out << config;
|
||||
|
||||
std::ofstream ofstrm(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
ofstrm << out.c_str();
|
||||
}
|
||||
else
|
||||
SH_LOG_ERROR("Error! Cannot store sash pos values.");
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
int cSerializer::DeserializeSplitterSashPos(std::string key) const
|
||||
{
|
||||
int pos = 0;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (auto bar = config["Window"])
|
||||
{
|
||||
if (key == "top")
|
||||
pos = bar["TopSplitterSashPos"].as<int>();
|
||||
|
||||
if (key == "bottom")
|
||||
pos = bar["BottomSplitterSashPos"].as<int>();
|
||||
}
|
||||
else
|
||||
{
|
||||
SH_LOG_ERROR("Error! Cannot fetch sash pos values.");
|
||||
}
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
void cSerializer::SerializeMediaOptions(std::string key, bool value)
|
||||
{
|
||||
YAML::Emitter out;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (auto media = config["Media"])
|
||||
{
|
||||
if (key == "autoplay")
|
||||
media["Autoplay"] = value;
|
||||
|
||||
if (key == "loop")
|
||||
media["Loop"] = value;
|
||||
|
||||
if (key == "muted")
|
||||
media["Muted"] = value;
|
||||
|
||||
out << config;
|
||||
|
||||
std::ofstream ofstrm(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
ofstrm << out.c_str();
|
||||
}
|
||||
else
|
||||
SH_LOG_ERROR("Error! Cannot store media values.");
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
bool cSerializer::DeserializeMediaOptions(std::string key) const
|
||||
{
|
||||
bool control = false;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (auto media = config["Media"])
|
||||
{
|
||||
if (key == "autoplay")
|
||||
control = media["Autoplay"].as<bool>();
|
||||
|
||||
if (key == "loop")
|
||||
control = media["Loop"].as<bool>();
|
||||
|
||||
if (key == "muted")
|
||||
control = media["Muted"].as<bool>();
|
||||
}
|
||||
else
|
||||
SH_LOG_ERROR("Error! Cannot fetch media values.");
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
|
||||
SH_LOG_INFO("{}: {}", key, control ? "enabled" : "disabled");
|
||||
|
||||
return control;
|
||||
}
|
||||
|
||||
void cSerializer::SerializeMediaVolume(int volume)
|
||||
{
|
||||
YAML::Emitter out;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (auto media = config["Media"])
|
||||
{
|
||||
media["Volume"] = volume;
|
||||
|
||||
out << config;
|
||||
|
||||
std::ofstream ofstrm(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
ofstrm << out.c_str();
|
||||
}
|
||||
else
|
||||
SH_LOG_ERROR("Error! Cannot store volume values.");
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
int cSerializer::DeserializeMediaVolume() const
|
||||
{
|
||||
int volume = 0;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (auto media = config["Media"])
|
||||
volume = media["Volume"].as<int>();
|
||||
else
|
||||
SH_LOG_ERROR("Error! Cannot fetch volume values.");
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
|
||||
SH_LOG_INFO("Volume: {}", volume);
|
||||
|
||||
return volume;
|
||||
}
|
||||
|
||||
void cSerializer::SerializeFontSettings(wxFont& font)
|
||||
{
|
||||
YAML::Emitter out;
|
||||
|
||||
std::string font_face = font.GetFaceName().ToStdString();
|
||||
int font_size = font.GetPointSize();
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
auto display = config["Display"];
|
||||
|
||||
if (auto fontSetting = display["Font"])
|
||||
{
|
||||
fontSetting["Family"] = font_face;
|
||||
fontSetting["Size"] = font_size;
|
||||
|
||||
out << config;
|
||||
|
||||
std::ofstream ofstrm(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
ofstrm << out.c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
SH_LOG_ERROR("Error! Cannot store font values.");
|
||||
}
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
wxFont cSerializer::DeserializeFontSettings() const
|
||||
{
|
||||
wxFont font;
|
||||
|
||||
wxString face;
|
||||
int size = 0 ;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
auto display = config["Display"];
|
||||
|
||||
if (auto font_setting = display["Font"])
|
||||
{
|
||||
face = font_setting["Family"].as<std::string>();
|
||||
size = font_setting["Size"].as<int>();
|
||||
|
||||
font.SetFaceName(face);
|
||||
font.SetPointSize(size);
|
||||
}
|
||||
else
|
||||
{
|
||||
SH_LOG_ERROR("Error! Cannot fetch font values.");
|
||||
}
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
void cSerializer::SerializeWaveformColour(wxColour& colour)
|
||||
{
|
||||
YAML::Emitter out;
|
||||
|
||||
std::string colour_string = colour.GetAsString(wxC2S_HTML_SYNTAX).ToStdString();
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
auto display = config["Display"];
|
||||
|
||||
if (auto waveform = display["Waveform"])
|
||||
{
|
||||
waveform["Colour"] = colour_string;
|
||||
|
||||
out << config;
|
||||
|
||||
std::ofstream ofstrm(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
ofstrm << out.c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
SH_LOG_ERROR("Error! Cannot store waveform colour.");
|
||||
}
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
wxColour cSerializer::DeserializeWaveformColour() const
|
||||
{
|
||||
std::string colour;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
auto display = config["Display"];
|
||||
|
||||
if (auto waveform = display["Waveform"])
|
||||
{
|
||||
colour = waveform["Colour"].as<std::string>();
|
||||
}
|
||||
else
|
||||
{
|
||||
SH_LOG_ERROR("Error! Cannot fetch waveform colour.");
|
||||
}
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
|
||||
return static_cast<wxString>(colour);
|
||||
}
|
||||
|
||||
void cSerializer::SerializeShowSplash(bool value)
|
||||
{
|
||||
YAML::Emitter out;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
auto display = config["Display"];
|
||||
|
||||
if (auto splash = display["Splash"])
|
||||
{
|
||||
splash["ShowSplashOnStartup"] = value;
|
||||
|
||||
out << config;
|
||||
|
||||
std::ofstream ofstrm(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
ofstrm << out.c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
SH_LOG_ERROR("Error! Cannot store show splash value.");
|
||||
}
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
bool cSerializer::DeserializeShowSplash() const
|
||||
{
|
||||
bool show = false;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
auto display = config["Display"];
|
||||
|
||||
if (auto splash = display["Splash"])
|
||||
{
|
||||
show = splash["ShowSplashOnStartup"].as<bool>();
|
||||
}
|
||||
else
|
||||
{
|
||||
SH_LOG_ERROR("Error! Cannot fetch show splash value.");
|
||||
}
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
|
||||
return show;
|
||||
}
|
||||
|
||||
void cSerializer::SerializeAutoImport(bool autoImport, const std::string& importDir)
|
||||
{
|
||||
YAML::Emitter out;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (auto autoImportInfo = config["Collection"])
|
||||
{
|
||||
autoImportInfo["AutoImport"] = autoImport;
|
||||
autoImportInfo["Directory"] = importDir;
|
||||
|
||||
out << config;
|
||||
|
||||
std::ofstream ofstrm(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
ofstrm << out.c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
SH_LOG_ERROR("Error! Cannot store import dir values.");
|
||||
}
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
ImportDirInfo cSerializer::DeserializeAutoImport() const
|
||||
{
|
||||
wxString dir;
|
||||
bool auto_import = false;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (auto autoImportInfo = config["Collection"])
|
||||
{
|
||||
auto_import = autoImportInfo["AutoImport"].as<bool>();
|
||||
dir = autoImportInfo["Directory"].as<std::string>();
|
||||
}
|
||||
else
|
||||
{
|
||||
SH_LOG_ERROR("Error! Cannot fetch import dir values.");
|
||||
}
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
|
||||
return { auto_import, dir };
|
||||
}
|
||||
|
||||
void cSerializer::SerializeFollowSymLink(bool followSymLinks)
|
||||
{
|
||||
YAML::Emitter out;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (auto followSymLinks = config["Collection"])
|
||||
{
|
||||
followSymLinks["FollowSymLink"] = followSymLinks;
|
||||
|
||||
out << config;
|
||||
|
||||
std::ofstream ofstrm(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
ofstrm << out.c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
SH_LOG_ERROR("Error! Cannot store follow symbolic links value.");
|
||||
}
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
bool cSerializer::DeserializeFollowSymLink() const
|
||||
{
|
||||
bool follow_sym_links = false;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (auto followSymLinks = config["Collection"])
|
||||
{
|
||||
follow_sym_links = followSymLinks["FollowSymLink"].as<bool>();
|
||||
}
|
||||
else
|
||||
{
|
||||
SH_LOG_ERROR("Error! Cannot fetch follow symbolic links value.");
|
||||
}
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
|
||||
return follow_sym_links;
|
||||
}
|
||||
|
||||
void cSerializer::SerializeRecursiveImport(bool recursiveImport)
|
||||
{
|
||||
YAML::Emitter out;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (auto recursive = config["Collection"])
|
||||
{
|
||||
recursive["RecursiveImport"] = recursiveImport;
|
||||
|
||||
out << config;
|
||||
|
||||
std::ofstream ofstrm(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
ofstrm << out.c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
SH_LOG_ERROR("Error! Cannot store recursive import value.");
|
||||
}
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
bool cSerializer::DeserializeRecursiveImport() const
|
||||
{
|
||||
bool recursive_import = false;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (auto recursive = config["Collection"])
|
||||
{
|
||||
recursive_import = recursive["RecursiveImport"].as<bool>();
|
||||
}
|
||||
else
|
||||
{
|
||||
SH_LOG_ERROR("Error! Cannot fetch recursive import value.");
|
||||
}
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
|
||||
return recursive_import;
|
||||
}
|
||||
|
||||
void cSerializer::SerializeShowFileExtension(bool showExtension)
|
||||
{
|
||||
YAML::Emitter out;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (auto fileExtensionInfo = config["Collection"])
|
||||
{
|
||||
fileExtensionInfo["ShowFileExtension"] = showExtension;
|
||||
|
||||
out << config;
|
||||
|
||||
std::ofstream ofstrm(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
ofstrm << out.c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
SH_LOG_ERROR("Error! Cannot store show file extension value.");
|
||||
}
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
bool cSerializer::DeserializeShowFileExtension() const
|
||||
{
|
||||
bool show_extension = false;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (auto fileExtensionInfo = config["Collection"])
|
||||
{
|
||||
show_extension = fileExtensionInfo["ShowFileExtension"].as<bool>();
|
||||
}
|
||||
else
|
||||
{
|
||||
SH_LOG_ERROR("Error! Cannot fetch show file extension value.");
|
||||
}
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
|
||||
return show_extension;
|
||||
}
|
||||
|
||||
void cSerializer::SerializeDoubleClickToPlay(bool enableDoubleClick)
|
||||
{
|
||||
YAML::Emitter out;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (auto doubleClickValue = config["Collection"])
|
||||
{
|
||||
doubleClickValue["DoubleClickToPlay"] = enableDoubleClick;
|
||||
|
||||
out << config;
|
||||
|
||||
std::ofstream ofstrm(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
ofstrm << out.c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
SH_LOG_ERROR("Error! Cannot store show enable double click to play value.");
|
||||
}
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
bool cSerializer::DeserializeDoubleClickToPlay() const
|
||||
{
|
||||
bool double_click_to_play = false;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (auto doubleClickValue = config["Collection"])
|
||||
{
|
||||
double_click_to_play = doubleClickValue["DoubleClickToPlay"].as<bool>();
|
||||
}
|
||||
else
|
||||
{
|
||||
SH_LOG_ERROR("Error! Cannot fetch double click to play value.");
|
||||
}
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
|
||||
return double_click_to_play;
|
||||
}
|
||||
|
||||
void cSerializer::SerializeDemoMode(bool showDemoMode)
|
||||
{
|
||||
YAML::Emitter out;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (auto general = config["General"])
|
||||
{
|
||||
general["DemoMode"] = showDemoMode;
|
||||
|
||||
out << config;
|
||||
|
||||
std::ofstream ofstrm(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
ofstrm << out.c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
SH_LOG_ERROR("Error! Cannot store show demo mode value.");
|
||||
}
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
bool cSerializer::DeserializeDemoMode() const
|
||||
{
|
||||
bool show_demo_mode = false;
|
||||
|
||||
try
|
||||
{
|
||||
YAML::Node config = YAML::LoadFile(static_cast<std::string>(CONFIG_FILEPATH));
|
||||
|
||||
if (auto general = config["General"])
|
||||
{
|
||||
show_demo_mode = general["DemoMode"].as<bool>();
|
||||
}
|
||||
else
|
||||
{
|
||||
SH_LOG_ERROR("Error! Cannot fetch show demo mode value.");
|
||||
}
|
||||
}
|
||||
catch (const YAML::ParserException& ex)
|
||||
{
|
||||
SH_LOG_ERROR(ex.what());
|
||||
}
|
||||
|
||||
return show_demo_mode;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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>
|
||||
|
||||
typedef std::pair<int, int> WindowSize;
|
||||
// typedef std::pair<wxString, int> FontType;
|
||||
typedef std::pair<bool, wxString> ImportDirInfo;
|
||||
|
||||
namespace SampleHive {
|
||||
|
||||
class cSerializer
|
||||
{
|
||||
public:
|
||||
cSerializer();
|
||||
~cSerializer();
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
// Window size
|
||||
void SerializeWinSize(int w, int h);
|
||||
WindowSize DeserializeWinSize() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Menu and status bar
|
||||
void SerializeShowMenuAndStatusBar(std::string key, bool value);
|
||||
bool DeserializeShowMenuAndStatusBar(std::string key) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Splitter window sash pos
|
||||
void SerializeSplitterSashPos(std::string key, int pos);
|
||||
int DeserializeSplitterSashPos(std::string key) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Browser controls
|
||||
void SerializeMediaOptions(std::string key, bool value);
|
||||
bool DeserializeMediaOptions(std::string key) const;
|
||||
|
||||
void SerializeMediaVolume(int volume);
|
||||
int DeserializeMediaVolume() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Display settings
|
||||
void SerializeFontSettings(wxFont& font);
|
||||
wxFont DeserializeFontSettings() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Waveform colour
|
||||
void SerializeWaveformColour(wxColour& colour);
|
||||
wxColour DeserializeWaveformColour() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Splash screen
|
||||
void SerializeShowSplash(bool value);
|
||||
bool DeserializeShowSplash() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Auto import settings
|
||||
void SerializeAutoImport(bool autoImport, const std::string& importDir);
|
||||
ImportDirInfo DeserializeAutoImport() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Follow symbolic links
|
||||
void SerializeFollowSymLink(bool followSymLink);
|
||||
bool DeserializeFollowSymLink() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Recursive import
|
||||
void SerializeRecursiveImport(bool recursiveImport);
|
||||
bool DeserializeRecursiveImport() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Show file extension
|
||||
void SerializeShowFileExtension(bool showExtension);
|
||||
bool DeserializeShowFileExtension() const;
|
||||
|
||||
// Enable double click to play
|
||||
void SerializeDoubleClickToPlay(bool showExtension);
|
||||
bool DeserializeDoubleClickToPlay() const;
|
||||
|
||||
// Demo mode
|
||||
void SerializeDemoMode(bool showDemoMode);
|
||||
bool DeserializeDemoMode() const;
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
YAML::Emitter m_Emitter;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Utility/Signal.hpp"
|
||||
#include "Utility/Log.hpp"
|
||||
#include "Utility/Event.hpp"
|
||||
|
||||
namespace SampleHive {
|
||||
|
||||
void cSignal::SendInfoBarMessage(const wxString& msg, int mode, wxWindow& window, bool isDialog)
|
||||
{
|
||||
SampleHive::cInfoBarMessageEvent event(SampleHive::SH_EVT_INFOBAR_MESSAGE_SHOW, window.GetId());
|
||||
event.SetEventObject(&window);
|
||||
|
||||
event.SetInfoBarMessage({ msg, mode });
|
||||
|
||||
if (isDialog)
|
||||
window.GetParent()->GetEventHandler()->ProcessEvent(event);
|
||||
else
|
||||
window.HandleWindowEvent(event);
|
||||
}
|
||||
|
||||
void cSignal::SendPushStatusBarStatus(const wxString& msg, int section, wxWindow& window, bool isDialog)
|
||||
{
|
||||
SampleHive::cStatusBarStatusEvent event(SampleHive::SH_EVT_STATUSBAR_STATUS_PUSH, window.GetId());
|
||||
event.SetEventObject(&window);
|
||||
|
||||
event.SetPushMessageAndSection({ msg, section });
|
||||
|
||||
if (isDialog)
|
||||
window.GetParent()->GetEventHandler()->ProcessEvent(event);
|
||||
else
|
||||
window.HandleWindowEvent(event);
|
||||
}
|
||||
|
||||
void cSignal::SendPopStatusBarStatus(int section, wxWindow& window, bool isDialog)
|
||||
{
|
||||
SampleHive::cStatusBarStatusEvent event(SampleHive::SH_EVT_STATUSBAR_STATUS_POP, window.GetId());
|
||||
event.SetEventObject(&window);
|
||||
|
||||
event.SetPopMessageSection(section);
|
||||
|
||||
if (isDialog)
|
||||
window.GetParent()->GetEventHandler()->ProcessEvent(event);
|
||||
else
|
||||
window.HandleWindowEvent(event);
|
||||
}
|
||||
|
||||
void cSignal::SendSetStatusBarStatus(const wxString& text, int section, wxWindow& window, bool isDialog)
|
||||
{
|
||||
SampleHive::cStatusBarStatusEvent event(SampleHive::SH_EVT_STATUSBAR_STATUS_SET, window.GetId());
|
||||
event.SetEventObject(&window);
|
||||
|
||||
event.SetStatusTextAndSection({ text, section });
|
||||
|
||||
if (isDialog)
|
||||
window.GetParent()->GetEventHandler()->ProcessEvent(event);
|
||||
else
|
||||
window.HandleWindowEvent(event);
|
||||
}
|
||||
|
||||
void cSignal::SendCallFunctionPlay(const wxString& selection, bool checkAutoplay, wxWindow& window, bool isDialog)
|
||||
{
|
||||
SampleHive::cCallFunctionEvent event(SampleHive::SH_EVT_CALL_FUNC_PLAY, window.GetId());
|
||||
event.SetEventObject(&window);
|
||||
|
||||
event.SetSelection(selection);
|
||||
event.SetAutoplayValue(checkAutoplay);
|
||||
|
||||
if (isDialog)
|
||||
window.GetParent()->GetEventHandler()->ProcessEvent(event);
|
||||
else
|
||||
window.HandleWindowEvent(event);
|
||||
}
|
||||
|
||||
void cSignal::SendTimerStopStatus(wxWindow& window, bool isDialog)
|
||||
{
|
||||
SampleHive::cTimerEvent event(SampleHive::SH_EVT_TIMER_STOP, window.GetId());
|
||||
event.SetEventObject(&window);
|
||||
|
||||
if (isDialog)
|
||||
window.GetParent()->GetEventHandler()->ProcessEvent(event);
|
||||
else
|
||||
window.HandleWindowEvent(event);
|
||||
}
|
||||
|
||||
void cSignal::SendLoopPoints(std::pair<double, double> loopPoint, wxWindow& window, bool isDialog)
|
||||
{
|
||||
SampleHive::cLoopPointsEvent event(SampleHive::SH_EVT_LOOP_POINTS_UPDATED, window.GetId());
|
||||
event.SetEventObject(&window);
|
||||
|
||||
event.SetLoopPoints({loopPoint.first, loopPoint.second});
|
||||
|
||||
if (isDialog)
|
||||
window.GetParent()->GetEventHandler()->ProcessEvent(event);
|
||||
else
|
||||
window.HandleWindowEvent(event);
|
||||
}
|
||||
|
||||
void cSignal::SendClearLoopPointsStatus(wxWindow& window, bool isDialog)
|
||||
{
|
||||
SampleHive::cLoopPointsEvent event(SampleHive::SH_EVT_LOOP_POINTS_CLEAR, window.GetId());
|
||||
event.SetEventObject(&window);
|
||||
|
||||
if (isDialog)
|
||||
window.GetParent()->GetEventHandler()->ProcessEvent(event);
|
||||
else
|
||||
window.HandleWindowEvent(event);
|
||||
}
|
||||
|
||||
void cSignal::SendLoopABButtonValueChange(wxWindow& window, bool isDialog)
|
||||
{
|
||||
SampleHive::cLoopPointsEvent event(SampleHive::SH_EVT_LOOP_AB_BUTTON_VALUE_CHANGE, window.GetId());
|
||||
event.SetEventObject(&window);
|
||||
|
||||
if (isDialog)
|
||||
window.GetParent()->GetEventHandler()->ProcessEvent(event);
|
||||
else
|
||||
window.HandleWindowEvent(event);
|
||||
}
|
||||
|
||||
void cSignal::SendWaveformUpdateStatus(wxWindow& window, bool isDialog)
|
||||
{
|
||||
SampleHive::cWaveformUpdateEvent event(SampleHive::SH_EVT_UPDATE_WAVEFORM, window.GetId());
|
||||
event.SetEventObject(&window);
|
||||
|
||||
if (isDialog)
|
||||
window.GetParent()->GetEventHandler()->ProcessEvent(event);
|
||||
else
|
||||
window.HandleWindowEvent(event);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wx/string.h>
|
||||
#include <wx/window.h>
|
||||
|
||||
namespace SampleHive {
|
||||
|
||||
class cSignal
|
||||
{
|
||||
public:
|
||||
cSignal();
|
||||
~cSignal();
|
||||
|
||||
public:
|
||||
static void SendInfoBarMessage(const wxString& msg, int mode, wxWindow& window, bool isDialog = false);
|
||||
static void SendPushStatusBarStatus(const wxString& msg, int section, wxWindow& window, bool isDialog = false);
|
||||
static void SendSetStatusBarStatus(const wxString& msg, int section, wxWindow& window, bool isDialog = false);
|
||||
static void SendPopStatusBarStatus(int section, wxWindow& window, bool isDialog = false);
|
||||
static void SendCallFunctionPlay(const wxString& selection, bool checkAutoplay, wxWindow& window, bool isDialog = false);
|
||||
static void SendTimerStopStatus(wxWindow& window, bool isDialog = false);
|
||||
static void SendLoopPoints(std::pair<double, double> loopPoint, wxWindow& window, bool isDialog = false);
|
||||
static void SendClearLoopPointsStatus(wxWindow& window, bool isDialog = false);
|
||||
static void SendLoopABButtonValueChange(wxWindow& window, bool isDialog = false);
|
||||
static void SendWaveformUpdateStatus(wxWindow& window, bool isDialog = false);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,157 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Utility/Tags.hpp"
|
||||
#include "SampleHiveConfig.hpp"
|
||||
|
||||
// #include <iomanip>
|
||||
|
||||
#include <taglib/tag.h>
|
||||
#include <taglib/fileref.h>
|
||||
// #include <taglib/tpropertymap.h>
|
||||
|
||||
#ifndef USE_SYSTEM_INCLUDE_PATH
|
||||
#include <taglib/toolkit/tstring.h>
|
||||
#else
|
||||
#include <taglib/tstring.h>
|
||||
#endif
|
||||
|
||||
namespace SampleHive {
|
||||
|
||||
cTags::cTags(const std::string& filename)
|
||||
: m_Filepath(filename)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
cTags::~cTags()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
cTags::AudioInfo cTags::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));
|
||||
|
||||
m_bValid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bValid = false;
|
||||
}
|
||||
|
||||
return { title, artist, album, genre, comment, channels, length, sample_rate, bitrate };
|
||||
}
|
||||
|
||||
void cTags::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 cTags::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 cTags::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 cTags::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 cTags::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,69 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <wx/string.h>
|
||||
|
||||
namespace SampleHive {
|
||||
|
||||
class cTags
|
||||
{
|
||||
struct AudioInfo
|
||||
{
|
||||
wxString title;
|
||||
wxString artist;
|
||||
wxString album;
|
||||
wxString genre;
|
||||
wxString comment;
|
||||
|
||||
int channels;
|
||||
int length;
|
||||
int sample_rate;
|
||||
int bitrate;
|
||||
};
|
||||
|
||||
public:
|
||||
cTags(const std::string& filepath);
|
||||
~cTags();
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
cTags::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 m_bValid; }
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
const std::string& m_Filepath;
|
||||
|
||||
bool m_bValid = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,332 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "Database/Database.hpp"
|
||||
#include "Utility/HiveData.hpp"
|
||||
#include "Utility/Log.hpp"
|
||||
#include "Utility/Paths.hpp"
|
||||
#include "Utility/Serialize.hpp"
|
||||
#include "Utility/Signal.hpp"
|
||||
#include "Utility/Tags.hpp"
|
||||
#include "Utility/Utils.hpp"
|
||||
|
||||
#include <wx/dir.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/progdlg.h>
|
||||
#include <wx/string.h>
|
||||
|
||||
#include <aubio/aubio.h>
|
||||
|
||||
namespace SampleHive {
|
||||
|
||||
SampleHive::cUtils::FileInfo SampleHive::cUtils::GetFilenamePathAndExtension(const wxString& selected,
|
||||
bool checkExtension, bool doGetFilename)
|
||||
{
|
||||
wxString path;
|
||||
std::string extension, filename;
|
||||
|
||||
path = GetSamplePath(selected);
|
||||
|
||||
if (checkExtension)
|
||||
extension = path.AfterLast('/').AfterLast('.').ToStdString();
|
||||
|
||||
if (doGetFilename)
|
||||
filename = path.AfterLast('/').BeforeLast('.').ToStdString();
|
||||
|
||||
return { path, extension, filename };
|
||||
}
|
||||
|
||||
void SampleHive::cUtils::AddSamples(wxArrayString& files, wxWindow* parent)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
cDatabase db;
|
||||
|
||||
wxBusyCursor busy_cursor;
|
||||
wxWindowDisabler window_disabler;
|
||||
|
||||
wxProgressDialog* progressDialog = new wxProgressDialog(_("Adding files.."),
|
||||
_("Adding files, please wait..."),
|
||||
static_cast<int>(files.size()), parent,
|
||||
wxPD_APP_MODAL | wxPD_SMOOTH | wxPD_CAN_ABORT |
|
||||
wxPD_AUTO_HIDE);
|
||||
progressDialog->CenterOnParent(wxBOTH);
|
||||
|
||||
std::vector<Sample> sample_array;
|
||||
|
||||
std::string path;
|
||||
std::string artist;
|
||||
std::string filename_with_extension;
|
||||
std::string filename_without_extension;
|
||||
std::string extension;
|
||||
std::string filename;
|
||||
|
||||
float bpm = 0.0f;
|
||||
float key = 0.0f;
|
||||
|
||||
//Check All Files At Once
|
||||
wxArrayString sorted_files;
|
||||
|
||||
if (!serializer.DeserializeDemoMode())
|
||||
{
|
||||
sorted_files = db.CheckDuplicates(files);
|
||||
files = sorted_files;
|
||||
}
|
||||
|
||||
if (files.size() < 1)
|
||||
{
|
||||
progressDialog->Destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
progressDialog->SetRange(files.size());
|
||||
|
||||
for (unsigned int i = 0; i < files.size(); i++)
|
||||
{
|
||||
progressDialog->Update(i, wxString::Format(_("Getting Data For %s"), files[i].AfterLast('/')));
|
||||
|
||||
if (progressDialog->WasCancelled())
|
||||
{
|
||||
progressDialog->Destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
path = files[i].ToStdString();
|
||||
filename_with_extension = files[i].AfterLast('/').ToStdString();
|
||||
filename_without_extension = files[i].AfterLast('/').BeforeLast('.').ToStdString();
|
||||
extension = files[i].AfterLast('.').ToStdString();
|
||||
|
||||
filename = serializer.DeserializeShowFileExtension() ?
|
||||
filename_with_extension : filename_without_extension;
|
||||
|
||||
bpm = GetBPM(path);
|
||||
|
||||
Sample sample;
|
||||
|
||||
sample.SetPath(path);
|
||||
sample.SetFilename(filename_without_extension);
|
||||
sample.SetFileExtension(extension);
|
||||
|
||||
cTags tags(path);
|
||||
|
||||
artist = tags.GetAudioInfo().artist.ToStdString();
|
||||
|
||||
sample.SetSamplePack(artist);
|
||||
sample.SetChannels(tags.GetAudioInfo().channels);
|
||||
sample.SetBPM(static_cast<int>(bpm));
|
||||
sample.SetLength(tags.GetAudioInfo().length);
|
||||
sample.SetSampleRate(tags.GetAudioInfo().sample_rate);
|
||||
sample.SetBitrate(tags.GetAudioInfo().bitrate);
|
||||
|
||||
wxString length = CalculateAndGetISOStandardTime(sample.GetLength());
|
||||
wxString bpm_str = GetBPMString(sample.GetBPM());
|
||||
|
||||
wxVector<wxVariant> data;
|
||||
|
||||
wxVariant icon = wxVariant(wxBitmap(ICON_STAR_EMPTY_16px, wxBITMAP_TYPE_PNG));
|
||||
|
||||
if (tags.IsFileValid())
|
||||
{
|
||||
data.clear();
|
||||
data.push_back(icon);
|
||||
data.push_back(filename);
|
||||
data.push_back(sample.GetSamplePack());
|
||||
data.push_back("");
|
||||
data.push_back(wxString::Format("%d", sample.GetChannels()));
|
||||
data.push_back(bpm_str);
|
||||
data.push_back(length);
|
||||
data.push_back(wxString::Format("%d", sample.GetSampleRate()));
|
||||
data.push_back(wxString::Format("%d", sample.GetBitrate()));
|
||||
data.push_back(path);
|
||||
|
||||
SH_LOG_INFO("Adding file: {}, Extension: {}", sample.GetFilename(), sample.GetFileExtension());
|
||||
|
||||
SampleHive::cHiveData::Get().ListCtrlAppendItem(data);
|
||||
|
||||
sample_array.push_back(sample);
|
||||
}
|
||||
else
|
||||
{
|
||||
wxString msg = wxString::Format(_("Error! Cannot open %s, Invalid file type."),
|
||||
filename_with_extension);
|
||||
|
||||
SampleHive::cSignal::SendInfoBarMessage(msg, wxICON_ERROR, *parent);
|
||||
}
|
||||
}
|
||||
|
||||
progressDialog->Pulse(_("Updating Database.."), NULL);
|
||||
|
||||
db.InsertIntoSamples(sample_array);
|
||||
|
||||
progressDialog->Destroy();
|
||||
}
|
||||
|
||||
void cUtils::OnAutoImportDir(const wxString& pathToDirectory, wxWindow* parent)
|
||||
{
|
||||
SH_LOG_DEBUG("Start Importing Samples");
|
||||
|
||||
wxBusyCursor busy_cursor;
|
||||
wxWindowDisabler window_disabler;
|
||||
|
||||
wxString filepath;
|
||||
wxArrayString filepath_array;
|
||||
|
||||
size_t number_of_files = wxDir::GetAllFiles(pathToDirectory, &filepath_array, wxEmptyString, wxDIR_DEFAULT);
|
||||
|
||||
wxProgressDialog* progressDialog = new wxProgressDialog(_("Adding files.."),
|
||||
_("Adding files, please wait..."),
|
||||
static_cast<int>(number_of_files), parent,
|
||||
wxPD_APP_MODAL | wxPD_SMOOTH |
|
||||
wxPD_CAN_ABORT | wxPD_AUTO_HIDE);
|
||||
|
||||
progressDialog->CenterOnParent(wxBOTH);
|
||||
|
||||
for (size_t i = 0; i < number_of_files; i++)
|
||||
{
|
||||
filepath = filepath_array[i];
|
||||
|
||||
if (wxFileExists(filepath))
|
||||
{
|
||||
filepath_array.push_back(filepath);
|
||||
}
|
||||
else if (wxDirExists(filepath))
|
||||
{
|
||||
wxDir::GetAllFiles(filepath, &filepath_array);
|
||||
}
|
||||
|
||||
progressDialog->Pulse(_("Reading Samples"), NULL);
|
||||
}
|
||||
|
||||
progressDialog->Destroy();
|
||||
|
||||
AddSamples(filepath_array, parent);
|
||||
|
||||
SH_LOG_DEBUG("Done Importing Samples");
|
||||
}
|
||||
|
||||
std::string cUtils::GetSamplePath(const wxString& name)
|
||||
{
|
||||
SampleHive::cSerializer serializer;
|
||||
cDatabase db;
|
||||
|
||||
wxString sample_path;
|
||||
|
||||
if (m_PathCache.find(name.ToStdString()) != m_PathCache.end())
|
||||
return m_PathCache[name.ToStdString()];
|
||||
else
|
||||
{
|
||||
sample_path = serializer.DeserializeShowFileExtension() ?
|
||||
db.GetSamplePathByFilename(name.BeforeLast('.').ToStdString()) :
|
||||
db.GetSamplePathByFilename(name.ToStdString());
|
||||
|
||||
m_PathCache[name.ToStdString()] = sample_path;
|
||||
}
|
||||
|
||||
return sample_path.ToStdString();
|
||||
}
|
||||
|
||||
wxString cUtils::CalculateAndGetISOStandardTime(wxLongLong length)
|
||||
{
|
||||
const int min_digits = 2;
|
||||
const size_t max_digits = 2;
|
||||
wxString iso_length;
|
||||
|
||||
int min = static_cast<int>((length / 60000).GetValue());
|
||||
int sec = static_cast<int>(((length % 60000) / 1000).GetValue());
|
||||
int ms = static_cast<int>((length % 1000).GetValue());
|
||||
|
||||
iso_length = wxString::Format("%s:%s.%s",
|
||||
wxString::Format("%0*i", min_digits, min).Left(max_digits),
|
||||
wxString::Format("%0*i", min_digits, sec).Left(max_digits),
|
||||
wxString::Format("%0*i", min_digits + 1, ms).Left(max_digits + 1));
|
||||
|
||||
return iso_length;
|
||||
}
|
||||
|
||||
wxString cUtils::GetBPMString(float bpm)
|
||||
{
|
||||
return wxString::Format("%d", static_cast<int>(bpm));
|
||||
}
|
||||
|
||||
float cUtils::GetBPM(const std::string& path)
|
||||
{
|
||||
uint_t buff_size = 1024, hop_size = buff_size / 2, frames = 0, samplerate = 0, read = 0;
|
||||
aubio_tempo_t* tempo;
|
||||
fvec_t* in, *out;
|
||||
aubio_source_t* source = new_aubio_source(path.c_str(), samplerate, hop_size);
|
||||
|
||||
float bpm = 0.0f;
|
||||
|
||||
if (!source)
|
||||
return 0.0f;
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
if (samplerate == 0)
|
||||
samplerate = aubio_source_get_samplerate(source);
|
||||
|
||||
tempo = new_aubio_tempo("default", buff_size, hop_size, samplerate);
|
||||
|
||||
if (!tempo)
|
||||
return 0.0f;
|
||||
|
||||
in = new_fvec(hop_size);
|
||||
out = new_fvec(1);
|
||||
|
||||
do
|
||||
{
|
||||
// put some fresh data in input vector
|
||||
aubio_source_do(source, in, &read);
|
||||
|
||||
// execute tempo
|
||||
aubio_tempo_do(tempo, in, out);
|
||||
|
||||
// do something with the beats
|
||||
// if (out->data[0] != 0)
|
||||
// {
|
||||
// SH_LOG_DEBUG("Track: {} Beat at {}s, {}s, frame {}, {} bpm with confidence {}",
|
||||
// path, aubio_tempo_get_last_ms(tempo), aubio_tempo_get_last_s(tempo),
|
||||
// aubio_tempo_get_last(tempo), aubio_tempo_get_bpm(tempo),
|
||||
// aubio_tempo_get_confidence(tempo));
|
||||
// }
|
||||
|
||||
frames += read;
|
||||
bpm = aubio_tempo_get_bpm(tempo);
|
||||
}
|
||||
while (read == hop_size);
|
||||
|
||||
// clean up memory
|
||||
del_aubio_tempo(tempo);
|
||||
del_fvec(in);
|
||||
del_fvec(out);
|
||||
del_aubio_source(source);
|
||||
aubio_cleanup();
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
SH_LOG_ERROR("Aubio Error! {}", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
return bpm;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/* SampleHive
|
||||
* Copyright (C) 2021 Apoorv Singh
|
||||
* A simple, modern audio sample browser/manager for GNU/Linux.
|
||||
*
|
||||
* This file is a part of SampleHive
|
||||
*
|
||||
* SampleHive is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* SampleHive is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "wx/arrstr.h"
|
||||
#include "wx/string.h"
|
||||
#include "wx/window.h"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace SampleHive {
|
||||
|
||||
class cUtils
|
||||
{
|
||||
private:
|
||||
cUtils() = default;
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
cUtils(const cUtils&) = delete;
|
||||
cUtils& operator=(const cUtils) = delete;
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
static cUtils& Get()
|
||||
{
|
||||
static cUtils s_cUtils;
|
||||
return s_cUtils;
|
||||
}
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
struct FileInfo
|
||||
{
|
||||
wxString Path;
|
||||
std::string Extension;
|
||||
std::string Filename;
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
cUtils::FileInfo GetFilenamePathAndExtension(const wxString& selected,
|
||||
bool checkExtension = true,
|
||||
bool doGetFilename = true);
|
||||
void AddSamples(wxArrayString& files, wxWindow* parent);
|
||||
void OnAutoImportDir(const wxString& pathToDirectory, wxWindow* parent);
|
||||
wxString CalculateAndGetISOStandardTime(wxLongLong length);
|
||||
wxString GetBPMString(float bpm);
|
||||
|
||||
float GetBPM(const std::string& path);
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
std::string GetSamplePath(const wxString& name);
|
||||
|
||||
private:
|
||||
// -------------------------------------------------------------------
|
||||
std::unordered_map<std::string, std::string> m_PathCache;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
[wrap-file]
|
||||
directory = libsndfile-1.2.2
|
||||
source_url = https://github.com/libsndfile/libsndfile/releases/download/1.2.2/libsndfile-1.2.2.tar.xz
|
||||
source_filename = libsndfile-1.2.2.tar.xz
|
||||
source_hash = 3799ca9924d3125038880367bf1468e53a1b7e3686a934f098b7e1d286cdb80e
|
||||
patch_filename = libsndfile_1.2.2-2_patch.zip
|
||||
patch_url = https://wrapdb.mesonbuild.com/v2/libsndfile_1.2.2-2/get_patch
|
||||
patch_hash = 47c69c9bdd3d3b2a3ca3834f7288f2527cbc399c15a13705a182b221942aa3a5
|
||||
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/libsndfile_1.2.2-2/libsndfile-1.2.2.tar.xz
|
||||
wrapdb_version = 1.2.2-2
|
||||
|
||||
[provide]
|
||||
sndfile = libsndfile_dep
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
[wrap-file]
|
||||
directory = spdlog-1.15.3
|
||||
source_url = https://github.com/gabime/spdlog/archive/refs/tags/v1.15.3.tar.gz
|
||||
source_filename = spdlog-1.15.3.tar.gz
|
||||
source_hash = 15a04e69c222eb6c01094b5c7ff8a249b36bb22788d72519646fb85feb267e67
|
||||
patch_filename = spdlog_1.15.3-4_patch.zip
|
||||
patch_url = https://wrapdb.mesonbuild.com/v2/spdlog_1.15.3-4/get_patch
|
||||
patch_hash = ccdc72f3d965980d5edd1a56129a9b7fa5f7c86f31e4ecf2dba6a6068829d4e2
|
||||
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/spdlog_1.15.3-4/spdlog-1.15.3.tar.gz
|
||||
wrapdb_version = 1.15.3-4
|
||||
|
||||
[provide]
|
||||
spdlog = spdlog_dep
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
[wrap-file]
|
||||
directory = sqlite-amalgamation-3500400
|
||||
source_url = https://www.sqlite.org/2025/sqlite-amalgamation-3500400.zip
|
||||
source_filename = sqlite-amalgamation-3500400.zip
|
||||
source_hash = 1d3049dd0f830a025a53105fc79fd2ab9431aea99e137809d064d8ee8356b032
|
||||
patch_filename = sqlite3_3.50.4-1_patch.zip
|
||||
patch_url = https://wrapdb.mesonbuild.com/v2/sqlite3_3.50.4-1/get_patch
|
||||
patch_hash = 61f23729c411d96d575b8d16c47a454f41b815de585289dec8daf855620ebc3e
|
||||
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/sqlite3_3.50.4-1/sqlite-amalgamation-3500400.zip
|
||||
wrapdb_version = 3.50.4-1
|
||||
|
||||
[provide]
|
||||
sqlite3 = sqlite3_dep
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
[wrap-file]
|
||||
directory = taglib-2.1.1
|
||||
source_url = https://github.com/taglib/taglib/archive/refs/tags/v2.1.1.tar.gz
|
||||
source_filename = taglib-2.1.1.tar.gz
|
||||
source_hash = bd57924496a272322d6f9252502da4e620b6ab9777992e8934779ebd64babd6e
|
||||
patch_filename = taglib_2.1.1-1_patch.zip
|
||||
patch_url = https://wrapdb.mesonbuild.com/v2/taglib_2.1.1-1/get_patch
|
||||
patch_hash = 2f872cf5c75b4a0e38177170d1f61314451488e9eea3ef04b6534caacaab27e5
|
||||
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/taglib_2.1.1-1/taglib-2.1.1.tar.gz
|
||||
wrapdb_version = 2.1.1-1
|
||||
|
||||
[provide]
|
||||
taglib = taglib_dep
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
[wrap-git]
|
||||
url = https://github.com/wxWidgets/wxWidgets
|
||||
revision = v3.2.8
|
||||
clone-recursive = true
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
[wrap-file]
|
||||
directory = yaml-cpp-0.8.0
|
||||
source_url = https://github.com/jbeder/yaml-cpp/archive/refs/tags/0.8.0.zip
|
||||
source_filename = yaml-cpp-0.8.0.zip
|
||||
source_hash = 334e80ab7b52e14c23f94e041c74bab0742f2281aad55f66be2f19f4b7747071
|
||||
patch_filename = yaml-cpp_0.8.0-1_patch.zip
|
||||
patch_url = https://wrapdb.mesonbuild.com/v2/yaml-cpp_0.8.0-1/get_patch
|
||||
patch_hash = bb7ae2e0941ab0e885a4ff2562aaa84979230087fc80c0b4eb283a44094d661b
|
||||
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/yaml-cpp_0.8.0-1/yaml-cpp-0.8.0.zip
|
||||
wrapdb_version = 0.8.0-1
|
||||
|
||||
[provide]
|
||||
dependency_names = yaml-cpp
|
||||