A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2014 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include <QWidget>
22#include <QApplication>
23#include <QDesktopWidget>
24#include <QFileDialog>
25#include <QAction>
26#include <QMenu>
27#include <QMenuBar>
28#include <QMessageBox>
29#include <QTabBar>
30#include <QCloseEvent>
31#include <QDebug>
32
33#include "mainwindow.h"
34#include "regtab.h"
35#include "regedit.h"
36
37/**
38 * DocumentTab
39 */
40void DocumentTab::OnModified(bool modified)
41{
42 if(m_tab)
43 m_tab->SetTabModified(this, modified);
44}
45
46void DocumentTab::SetTabWidget(DocumentTabWidget *tab)
47{
48 m_tab = tab;
49 SetTabName(m_tabname);
50}
51
52void DocumentTab::SetTabName(const QString& name)
53{
54 m_tabname = name;
55 if(m_tab)
56 m_tab->SetTabName(this, name);
57}
58
59/**
60 * DocumentTabWidget
61 */
62
63DocumentTabWidget::DocumentTabWidget()
64{
65 setMovable(true);
66 setTabsClosable(true);
67 connect(this, SIGNAL(tabCloseRequested(int)), this, SLOT(OnCloseTab(int)));
68}
69
70void DocumentTabWidget::SetTabModified(DocumentTab *doc, bool modified)
71{
72 int index = indexOf(doc->GetWidget());
73 if(modified)
74 setTabIcon(index, QIcon::fromTheme("document-save"));
75 else
76 setTabIcon(index, QIcon());
77}
78
79void DocumentTabWidget::SetTabName(DocumentTab *doc, const QString& name)
80{
81 setTabText(indexOf(doc->GetWidget()), name);
82}
83
84bool DocumentTabWidget::CloseTab(int index)
85{
86 QWidget *w = this->widget(index);
87 DocumentTab *doc = dynamic_cast< DocumentTab* >(w);
88 if(doc->Quit())
89 {
90 removeTab(index);
91 delete w;
92 return true;
93 }
94 else
95 return false;
96}
97
98void DocumentTabWidget::OnCloseTab(int index)
99{
100 CloseTab(index);
101}
102
103/**
104 * MainWindow
105 */
106
107MainWindow::MainWindow(Backend *backend)
108 :m_backend(backend)
109{
110 QAction *new_regtab_act = new QAction(YIconManager::Get()->GetIcon(YIconManager::DocumentNew),
111 tr("Register &Tab"), this);
112 QAction *new_regedit_act = new QAction(YIconManager::Get()->GetIcon(YIconManager::DocumentEdit),
113 tr("Register &Editor"), this);
114 QAction *load_desc_act = new QAction(YIconManager::Get()->GetIcon(YIconManager::DocumentOpen),
115 tr("&Soc Description"), this);
116 QAction *quit_act = new QAction(YIconManager::Get()->GetIcon(YIconManager::ApplicationExit),
117 tr("&Quit"), this);
118 QAction *about_act = new QAction(YIconManager::Get()->GetIcon(YIconManager::HelpAbout),
119 tr("&About"), this);
120 QAction *about_qt_act = new QAction(YIconManager::Get()->GetIcon(YIconManager::HelpAbout),
121 tr("About &Qt"), this);
122
123 connect(new_regtab_act, SIGNAL(triggered()), this, SLOT(OnNewRegTab()));
124 connect(new_regedit_act, SIGNAL(triggered()), this, SLOT(OnNewRegEdit()));
125 connect(load_desc_act, SIGNAL(triggered()), this, SLOT(OnLoadDesc()));
126 connect(quit_act, SIGNAL(triggered()), this, SLOT(OnQuit()));
127 connect(about_act, SIGNAL(triggered()), this, SLOT(OnAbout()));
128 connect(about_qt_act, SIGNAL(triggered()), this, SLOT(OnAboutQt()));
129
130 QMenu *app_menu = new QMenu;
131 QMenu *file_menu = app_menu->addMenu(tr("&File"));
132 QMenu *new_submenu = file_menu->addMenu(YIconManager::Get()->GetIcon(YIconManager::DocumentNew), "&New");
133 QMenu *load_submenu = file_menu->addMenu(YIconManager::Get()->GetIcon(YIconManager::DocumentOpen), "&Load");
134 file_menu->addAction(quit_act);
135
136 new_submenu->addAction(new_regtab_act);
137 new_submenu->addAction(new_regedit_act);
138
139 load_submenu->addAction(load_desc_act);
140
141 QMenu *about_menu = app_menu->addMenu(tr("&About"));
142 about_menu->addAction(about_act);
143 about_menu->addAction(about_qt_act);
144
145 m_tab = new DocumentTabWidget();
146 m_tab->setTabOpenable(true);
147 m_tab->setTabOpenMenu(new_submenu);
148 m_tab->setOtherMenu(app_menu);
149
150 setCentralWidget(m_tab);
151
152 ReadSettings();
153#ifdef HAVE_HWSTUB
154 /* acquire hwstub manager */
155 HWStubManager::Get()->setParent(this);
156#endif
157 /* acquire icon manager */
158 YIconManager::Get()->setParent(this);
159
160 OnNewRegTab();
161}
162
163void MainWindow::ReadSettings()
164{
165 restoreGeometry(Settings::Get()->value("mainwindow/geometry").toByteArray());
166}
167
168void MainWindow::WriteSettings()
169{
170 Settings::Get()->setValue("mainwindow/geometry", saveGeometry());
171}
172
173void MainWindow::OnQuit()
174{
175 close();
176}
177
178void MainWindow::OnAbout()
179{
180 QString soc_desc_ver = QString("%1.%2.%3").arg(soc_desc::MAJOR_VERSION)
181 .arg(soc_desc::MINOR_VERSION).arg(soc_desc::REVISION_VERSION);
182 QMessageBox::about(this, "About",
183 "<h1>QEditor</h1>"
184 "<h2>Version " APP_VERSION "</h2>"
185 "<p>Written by Amaury Pouly</p>"
186 "<p>Libraries:</p>"
187 "<ul><li>soc_desc: " + soc_desc_ver + "</li>"
188#ifdef HAVE_HWSTUB
189 "<li>hwstub: " HWSTUB_VERSION "</li>"
190#else
191 "<li>hwstub: not compiled in</li>"
192#endif
193 "</ul>");
194}
195
196void MainWindow::OnAboutQt()
197{
198 QMessageBox::aboutQt(this);
199}
200
201void MainWindow::closeEvent(QCloseEvent *event)
202{
203 if(!Quit())
204 return event->ignore();
205 WriteSettings();
206 event->accept();
207}
208
209void MainWindow::OnLoadDesc()
210{
211 QFileDialog *fd = new QFileDialog(this);
212 QStringList filters;
213 filters << "XML files (*.xml)";
214 filters << "All files (*)";
215 fd->setNameFilters(filters);
216 fd->setFileMode(QFileDialog::ExistingFiles);
217 fd->setDirectory(Settings::Get()->value("loaddescdir", QDir::currentPath()).toString());
218 if(fd->exec())
219 {
220 QStringList filenames = fd->selectedFiles();
221 for(int i = 0; i < filenames.size(); i++)
222 if(!m_backend->LoadSocDesc(filenames[i]))
223 {
224 QMessageBox msg;
225 msg.setText(QString("Cannot load ") + filenames[i]);
226 msg.exec();
227 }
228 Settings::Get()->setValue("loaddescdir", fd->directory().absolutePath());
229 }
230}
231
232void MainWindow::AddTab(DocumentTab *doc)
233{
234 m_tab->setCurrentIndex(m_tab->addTab(doc->GetWidget(), ""));
235 doc->SetTabWidget(m_tab);
236}
237
238void MainWindow::OnNewRegTab()
239{
240 AddTab(new RegTab(m_backend, this));
241}
242
243void MainWindow::OnNewRegEdit()
244{
245 AddTab(new RegEdit(m_backend, this));
246}
247
248bool MainWindow::Quit()
249{
250 while(m_tab->count() > 0)
251 {
252 if(!m_tab->CloseTab(0))
253 return false;
254 }
255 return true;
256}