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