Parcourir la source

Все настройки хранятся в одном месте

Вадим Королёв il y a 1 an
Parent
commit
88b6734e01
8 fichiers modifiés avec 188 ajouts et 107 suppressions
  1. 13 7
      src/YTMPV/MainWindow.cpp
  2. 73 45
      src/YTMPV/PrefWindow.cpp
  3. 4 14
      src/YTMPV/PrefWindow.hpp
  4. 16 20
      src/YTMPV/app.cpp
  5. 8 15
      src/YTMPV/app.hpp
  6. 42 1
      src/YTMPV/core.cpp
  7. 24 1
      src/YTMPV/core.hpp
  8. 8 4
      src/YTMPV/ytmpv.cpp

+ 13 - 7
src/YTMPV/MainWindow.cpp

@@ -26,7 +26,6 @@ namespace components {
         , m_head(Gtk::Orientation::VERTICAL)
         , m_body()
         , m_stackswitcher()
-        //~ , m_gears()
 
         , m_search_layout(Gtk::Orientation::VERTICAL)
         , m_search_head(Gtk::Orientation::HORIZONTAL)
@@ -187,11 +186,18 @@ namespace components {
         if (pid == 0) {
             std::string yt_url = "https://youtu.be/"+yt_id;
             execl(
-                "/usr/bin/mpv",     // Путь к mpv
-                "mpv",              // Название файла
-                "--no-terminal",    // Терминал не нужен
-                yt_url.c_str(),     // URL видео
-                (char*)0            // Терминатор
+                // Путь к mpv
+                "/usr/bin/mpv",
+                // Название файла
+                "mpv",
+                // Терминал не нужен
+                "--no-terminal",
+                // Качество
+                "--ytdl-format="+core::getYTDLFormat(core::Settings::getQuality()),
+                // URL видео
+                yt_url.c_str(),
+                // Терминатор
+                (char*)0
             );
         }
     }
@@ -315,4 +321,4 @@ namespace components {
         std::string command = "xdg-open https://youtu.be/"+yt_id;
         system(command.c_str());
     }
-}
+}

+ 73 - 45
src/YTMPV/PrefWindow.cpp

@@ -1,37 +1,20 @@
 #include "PrefWindow.hpp"
+#include "core.hpp"
 #include <array>
 #include <fstream>
 #include <iostream>
 #include <gtkmm/stringlist.h>
 #include <assert.h>
 #include <nlohmann/json.hpp>
+#include "app.hpp"
+#include <YoutubeApi/youtubeapi.hpp>
 
 using json = nlohmann::json;
 
-namespace
-{
-    struct QualityTypeStruct
-    {
-        // Значение ключа в Gio::Settings (240,360,480...)
-        int value;
-        // Текст для надписи
-        Glib::ustring text;
-    };
-
-    const std::array<QualityTypeStruct, 4> quality_types =
-    {
-        QualityTypeStruct{240, "240p"},
-        QualityTypeStruct{360, "360p"},
-        QualityTypeStruct{480, "480p"},
-        QualityTypeStruct{720, "720p"}
-    };
-} // anonymous namespace
-
 namespace components {
     PrefWindow::PrefWindow(
         BaseObjectType* cobject,
-        const Glib::RefPtr<Gtk::Builder>& refBuilder
-    )
+        const Glib::RefPtr<Gtk::Builder>& refBuilder)
         : Gtk::Window(cobject)
         , m_builder(refBuilder)
     {
@@ -41,7 +24,8 @@ namespace components {
             "240p",
             "360p",
             "480p",
-            "720p"
+            "720p",
+            "1080p"
         };
         
         m_quality_dropdown = m_builder->get_widget<Gtk::DropDown>("quality_entry");
@@ -58,25 +42,39 @@ namespace components {
         m_quality_dropdown->set_model(string_list);
 
         m_save_btn->signal_clicked().connect(sigc::mem_fun(
-            *this, &PrefWindow::on_save_clicked));
+            *this, &PrefWindow::onSaveClicked));
         m_cancel_btn->signal_clicked().connect(sigc::mem_fun(
-            *this, &PrefWindow::on_cancel_clicked));
-    }
+            *this, &PrefWindow::onCancelClicked));
 
-    void PrefWindow::init(
-        std::string config_path,
-        Glib::ustring api_key,
-        int quality
-    )
-    {
-        m_config_path = config_path;
-        m_apikey_entry->set_text(api_key);
+        m_apikey_entry->set_text(core::Settings::getApiKey());
+
+        int selected_quality_index;
+        switch(core::Settings::getQuality())
+        {
+            case 240:
+                selected_quality_index = 0;
+                break;
+            case 360:
+                selected_quality_index = 1;
+                break;
+            case 480:
+                selected_quality_index = 2;
+                break;
+            case 720:
+                selected_quality_index = 3;
+                break;
+            case 1080:
+                selected_quality_index = 4;
+                break;
+            default:
+                selected_quality_index = 0;
+                break;
+        }
+        m_quality_dropdown->set_selected(selected_quality_index);
     }
 
     PrefWindow* PrefWindow::create(
-        Gtk::Window& parent,
-        std::string config_path,
-        std::string api_key
+        Gtk::Window& parent
     )
     {
         auto builder = Gtk::Builder::create_from_resource("/src/YTMPV/res/PrefsWindow.ui");
@@ -84,33 +82,63 @@ namespace components {
         assert(win != nullptr);
 
         win->set_transient_for(parent);
-        win->init(config_path, api_key, 720);
         return win;
     }
 
-    void PrefWindow::on_cancel_clicked()
+    void PrefWindow::onCancelClicked()
     {
         this->close();
     }
 
-    void PrefWindow::on_save_clicked()
+    void PrefWindow::onSaveClicked()
     {
-        this->save_config();
+        this->saveConfig();
         this->close();
     }
 
-    void PrefWindow::save_config()
+    void PrefWindow::saveConfig()
     {
-        // Получение данных
+        // -- Получение данных --
+        // Ключ API
         Glib::ustring api_key = m_apikey_entry->get_text();
+
+        // Качество
+        int quality;
+        int sel_index = m_quality_dropdown->get_selected();
+        switch(sel_index)
+        {
+            case 0:
+                quality = 240;
+                break;
+            case 1:
+                quality = 360;
+                break;
+            case 2:
+                quality = 480;
+                break;
+            case 3:
+                quality = 720;
+                break;
+            case 4:
+                quality = 1080;
+                break;
+            default:
+                quality = 240;
+                break;
+        }
         
         // Сериализация
-        json j_object = { {"apikey", api_key}, {"quality", 480} };
+        json j_object = { {"apikey", api_key}, {"quality", quality} };
         std::string dump = j_object.dump(1, '\t');
 
         // Запись в файл
-        std::ofstream config(m_config_path);
+        std::ofstream config(core::Settings::getConfigPath());
         config << dump;
         config.close();
+
+        // Пере-инициализация библиотек
+        ytapi::youtubeInit(api_key);
+        core::Settings::setApiKey(api_key);
+        core::Settings::setQuality(quality);
     }
-}
+}

+ 4 - 14
src/YTMPV/PrefWindow.hpp

@@ -13,16 +13,8 @@ namespace components {
         PrefWindow(
             BaseObjectType* cobject,
             const Glib::RefPtr<Gtk::Builder>& refBuilder);
-        static PrefWindow* create(
-            Gtk::Window& parent,
-            std::string config_path,
-            std::string api_key);
 
-        // Инициализирует окно
-        void init(
-            std::string config_path,
-            Glib::ustring api_key,
-            int quality);
+        static PrefWindow* create(Gtk::Window& parent);
 
     protected:
         Glib::RefPtr<Gtk::Builder> m_builder;
@@ -31,13 +23,11 @@ namespace components {
         Gtk::Button* m_cancel_btn;
         Gtk::Button* m_save_btn;
 
-        std::string m_config_path;
-
         // -- Обработчики событий --
-        void on_cancel_clicked();
-        void on_save_clicked();
+        void onCancelClicked();
+        void onSaveClicked();
 
         // Сохраняет настройки
-        void save_config();
+        void saveConfig();
     };
 }

+ 16 - 20
src/YTMPV/app.cpp

@@ -2,47 +2,45 @@
 #include <iostream>
 #include <giomm/menu.h>
 #include <gtkmm/builder.h>
+#include <assert.h>
 
 namespace components {
-    App::App(std::string config_path, std::string api_key)
+    App::App()
         : Gtk::Application("com.github.aquadim.YTMPV")
-        , m_config_path(config_path)
-        , m_api_key(api_key)
     {
     }
 
-    Glib::RefPtr<App> App::create(std::string config_path, std::string api_key)
+    Glib::RefPtr<App> App::create()
     {
-        return Glib::make_refptr_for_instance<App>(new App(config_path, api_key));
+        auto app = Glib::make_refptr_for_instance<App>(new App());
+        return app;
     }
 
     void App::on_startup()
     {
         Gtk::Application::on_startup();
 
-        add_action("preferences", sigc::mem_fun(*this, &App::on_action_prefs));
+        add_action("preferences", sigc::mem_fun(*this, &App::onActionPrefs));
         set_accel_for_action("app.preferences", "<Ctrl>P");
 
-        add_action("quit", sigc::mem_fun(*this, &App::on_action_quit));
+        add_action("quit", sigc::mem_fun(*this, &App::onActionQuit));
         set_accel_for_action("app.quit", "<Ctrl>Q");
 
         // Установка менюбара
         auto menu_builder = Gtk::Builder::create_from_resource("/src/YTMPV/res/MainMenu.ui");
         auto menu = menu_builder->get_object<Gio::Menu>("menu");
-        if (!menu)
-        {
-            std::cout << "menu not found :(" << std::endl;
-        }
+        assert(menu != nullptr);
+        
         set_menubar(menu);
     }
 
     void App::on_activate()
     {
-        auto appwindow = create_appwindow();
+        auto appwindow = createMainWindow();
         appwindow->present();
     }
 
-    MainWindow* App::create_appwindow()
+    MainWindow* App::createMainWindow()
     {
         // Создание окна и привязка обработчика к его сигналу скрытия
         auto appwindow = MainWindow::create();
@@ -52,12 +50,10 @@ namespace components {
         return appwindow;
     }
 
-    PrefWindow* App::create_prefwindow()
+    PrefWindow* App::createPrefWindow()
     {
         auto prefwindow = PrefWindow::create(
-            *get_active_window(),
-            m_config_path,
-            m_api_key
+            *get_active_window()
         );
         add_window(*prefwindow);
         prefwindow->signal_hide().connect(
@@ -65,7 +61,7 @@ namespace components {
         return prefwindow;
     }
 
-    void App::on_action_quit()
+    void App::onActionQuit()
     {
         auto windows = get_windows();
         for (auto window : windows)
@@ -75,9 +71,9 @@ namespace components {
         quit();
     }
     
-    void App::on_action_prefs()
+    void App::onActionPrefs()
     {
-        PrefWindow* win = create_prefwindow();
+        PrefWindow* win = createPrefWindow();
         win->present();
     }
 }

+ 8 - 15
src/YTMPV/app.hpp

@@ -10,24 +10,17 @@ namespace components {
     class App: public Gtk::Application
     {
     public:
-        static Glib::RefPtr<App> create(
-            std::string config_path,
-            std::string api_key);
+        static Glib::RefPtr<App> create();
 
     protected:
-        App(
-            std::string config_path,
-            std::string api_key);
+        App();
         void on_startup() override;
         void on_activate() override;
-        void on_action_quit();
-        void on_action_prefs();
-
-        std::string m_config_path;
-        std::string m_api_key;
-
+        void onActionQuit();
+        void onActionPrefs();
+        
     private:
-        MainWindow* create_appwindow();
-        PrefWindow* create_prefwindow();
+        MainWindow* createMainWindow();
+        PrefWindow* createPrefWindow();
     };
-}
+}

+ 42 - 1
src/YTMPV/core.cpp

@@ -2,6 +2,7 @@
 #include <giomm/icon.h>
 #include <gtkmm/image.h>
 #include <gtkmm/label.h>
+#include <string>
 
 namespace core {
     
@@ -56,4 +57,44 @@ namespace core {
 
         return box_main;
     }
-}
+
+    std::string getYTDLFormat(int height)
+    {
+        return "bestvideo[height<=?"+std::to_string(height)+"]+bestaudio/best";
+    }
+
+    std::string Settings::s_config_path("");
+    std::string Settings::s_api_key("");
+    int Settings::s_quality(0);
+    
+    void Settings::setConfigPath(std::string config_path)
+    {
+        s_config_path = config_path;
+    }
+
+    void Settings::setApiKey(std::string api_key)
+    {
+        ytapi::youtubeInit(api_key);
+        s_api_key = api_key;
+    }
+
+    void Settings::setQuality(int quality)
+    {
+        s_quality = quality;
+    }
+
+    std::string Settings::getConfigPath()
+    {
+        return s_config_path;
+    }
+
+    std::string Settings::getApiKey()
+    {
+        return s_api_key;
+    }
+
+    int Settings::getQuality()
+    {
+        return s_quality;
+    }
+}

+ 24 - 1
src/YTMPV/core.hpp

@@ -13,4 +13,27 @@ namespace core {
 
     // Возвращает дочерний виджет для кнопок, которым нужны иконка с текстом
     Gtk::Box* getButtonContents(Glib::ustring text, std::string icon_name);
-}
+
+    // Возвращает строку формата yt-dl
+    std::string getYTDLFormat(int height);
+
+    class Settings {
+    public:
+        static void setConfigPath(std::string config_path);
+        static void setApiKey(std::string api_key);
+        static void setQuality(int quality);
+
+        static std::string getConfigPath();
+        static std::string getApiKey();
+        static int getQuality();
+
+        // Путь к файлу настроек
+        static std::string s_config_path;
+        
+        // Ключ API
+        static std::string s_api_key;
+
+        // Качество воспроизводимых видео (240/360/480/720/1080p)
+        static int s_quality;
+    };
+}

+ 8 - 4
src/YTMPV/ytmpv.cpp

@@ -1,4 +1,5 @@
 #include "app.hpp"
+#include "core.hpp"
 #include <glibmm.h>
 #include <curl/curl.h>
 #include <Database/database.hpp>
@@ -19,9 +20,9 @@ int main(int argc, char** argv) {
         "ytmpv",
         "config.json");
     std::ifstream config_file(config_path);
-    json j_config = json::parse(config_file);
+    auto j_config = json::parse(config_file);
     config_file.close();
-    
+
     // TODO
     std::string db_path = "/home/vad/Code/YTMPV/db.sqlite3";
     
@@ -32,6 +33,9 @@ int main(int argc, char** argv) {
     ytapi::youtubeInit(j_config["apikey"]);
 
     // -- Запуск приложения --
-    auto app = components::App::create(config_path, j_config["apikey"]);
+    core::Settings::setConfigPath(config_path);
+    core::Settings::setApiKey(j_config["apikey"]);
+    core::Settings::setQuality(j_config["quality"]);
+    auto app = components::App::create();
     return app->run(argc, argv);
-}
+}