From 8221037c77be1f7c256b2575d4a9a4a9d58a9c0d Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Sat, 27 May 2017 17:50:22 +0200 Subject: Profile improvements * Some code refactoring * Profile dialog UI is now only created when needed * Profile selector dialog --- CONTRIBUTING.md | 1 + data/bookmarks.xbel | 2 +- data/poi.toml | 2 +- docs/Design Notes.md | 11 +++-- smolbote.qbs | 5 +++ src/browser.cpp | 20 ++++++--- src/browser.h | 1 + src/forms/bookmarkswidget.cpp | 2 +- src/forms/profilesdialog.cpp | 54 +++++++++++++++++++++++++ src/forms/profilesdialog.h | 50 +++++++++++++++++++++++ src/forms/profilesdialog.ui | 74 +++++++++++++++++++++++++++++++++ src/main.cpp | 6 ++- src/mainwindow.cpp | 60 +++++---------------------- src/mainwindow.h | 18 ++++----- src/webengine/webengineprofile.cpp | 10 +++-- src/webengine/webengineprofile.h | 2 +- src/widgets/mainwindowmenubar.cpp | 83 ++++++++++++++++++++++++++++++++++++++ src/widgets/mainwindowmenubar.h | 40 ++++++++++++++++++ 18 files changed, 361 insertions(+), 80 deletions(-) create mode 100644 src/forms/profilesdialog.cpp create mode 100644 src/forms/profilesdialog.h create mode 100644 src/forms/profilesdialog.ui create mode 100644 src/widgets/mainwindowmenubar.cpp create mode 100644 src/widgets/mainwindowmenubar.h diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0913e5b..1cfe4ab 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,6 +34,7 @@ Major bugfixes and each new feature should get a revision. ### Branching * master - main branch, should be kept up-to-date, and have only working code +* next - next stable release preparation, mostly for bugfixes * development - development branch, anything goes there ### Folder structure diff --git a/data/bookmarks.xbel b/data/bookmarks.xbel index 5aab255..afcd006 100644 --- a/data/bookmarks.xbel +++ b/data/bookmarks.xbel @@ -3,7 +3,7 @@ smolbote - + Repository diff --git a/data/poi.toml b/data/poi.toml index 7359630..e2f37e6 100644 --- a/data/poi.toml +++ b/data/poi.toml @@ -18,7 +18,7 @@ localSocket="smolbote-singlelock" # Profile [browser.profile] -default="Default" +default="" # "" is off-the-record path="$cache/Profiles/" # Main window settings diff --git a/docs/Design Notes.md b/docs/Design Notes.md index 73ee83e..abb5362 100644 --- a/docs/Design Notes.md +++ b/docs/Design Notes.md @@ -4,15 +4,18 @@ The aim of this project is to provide a small and fast web browser. ### General * Use generic formats -### Implemented features -* - ### To do * Proper application-level profile manager +* Reorganize Profile menu +* System-level and user-level profile config, with per-profile overrides +* Default system-level config and user-level overrides +* Cookie filter list similar to the URL filter list +* Moving tabs between windows +* Tab context menu ## Dependencies * Qt, over 5.7 (up-to-date Qt version recommended) -+ qbs, over 1.6.0 (Qt 5.7) +* qbs, over 1.6.0 (Qt 5.7) ## Notes An optional system proxy should be picked up automatically. However, for proxies that require a username or password, you need to connect to QWebEnginePage::proxyAuthenticationRequired. diff --git a/smolbote.qbs b/smolbote.qbs index 087249a..18112f0 100644 --- a/smolbote.qbs +++ b/smolbote.qbs @@ -82,6 +82,8 @@ Project { "src/widgets/dockingwidget.h", "src/widgets/loadingbar.cpp", "src/widgets/loadingbar.h", + "src/widgets/mainwindowmenubar.cpp", + "src/widgets/mainwindowmenubar.h", "src/widgets/urllineedit.cpp", "src/widgets/urllineedit.h", "src/widgets/webviewtabbar.cpp", @@ -147,6 +149,9 @@ Project { "src/forms/profiledialog.cpp", "src/forms/profiledialog.h", "src/forms/profiledialog.ui", + "src/forms/profilesdialog.cpp", + "src/forms/profilesdialog.h", + "src/forms/profilesdialog.ui", "src/webengine/webengineprofile.cpp", "src/webengine/webengineprofile.h", ] diff --git a/src/browser.cpp b/src/browser.cpp index 9bf93e6..ca2b5d8 100644 --- a/src/browser.cpp +++ b/src/browser.cpp @@ -26,11 +26,6 @@ Browser::Browser(int &argc, char *argv[]) : QApplication(argc, argv) { - setApplicationName("smolbote"); - - // This lets the web view automatically scale on high-dpi displays. - setAttribute(Qt::AA_EnableHighDpiScaling); - m_settings = nullptr; m_localServer = nullptr; @@ -113,6 +108,10 @@ bool Browser::prepare(QStringList urls) QtWebEngine::initialize(); + // TODO properly + profile(""); + profile("Default"); + return true; } @@ -224,6 +223,15 @@ WebEngineProfile* Browser::profile(const QString name) return m_profiles[name]; } +QStringList Browser::profiles() +{ + QStringList l; + for(QString key : m_profiles.keys()) { + l.append(key); + } + return l; +} + void Browser::handleNewConnection() { QLocalSocket *socket = m_localServer->nextPendingConnection(); @@ -238,6 +246,6 @@ void Browser::handleNewConnection() QStringList::const_iterator i; for(i = urls.constBegin(); i != urls.constEnd(); ++i) { - mainWindow()->addNewTab(QUrl::fromUserInput(*i)); + mainWindow()->newTab(QUrl::fromUserInput(*i)); } } diff --git a/src/browser.h b/src/browser.h index a2e6513..6c3252f 100644 --- a/src/browser.h +++ b/src/browser.h @@ -63,6 +63,7 @@ public: MainWindow *mainWindow(); WebEngineProfile *profile(const QString name); + QStringList profiles(); public slots: void removeWindow(MainWindow* window); diff --git a/src/forms/bookmarkswidget.cpp b/src/forms/bookmarkswidget.cpp index ffb5d6c..9a43224 100644 --- a/src/forms/bookmarkswidget.cpp +++ b/src/forms/bookmarkswidget.cpp @@ -89,7 +89,7 @@ void BookmarksWidget::openItem(QTreeWidgetItem *item, int column) Q_UNUSED(column) if(window) { - window->addNewTab(QUrl::fromUserInput(item->text(1))); + window->newTab(QUrl::fromUserInput(item->text(1))); } else { qWarning("Trying to open a link without a MainWindow set"); } diff --git a/src/forms/profilesdialog.cpp b/src/forms/profilesdialog.cpp new file mode 100644 index 0000000..c77208d --- /dev/null +++ b/src/forms/profilesdialog.cpp @@ -0,0 +1,54 @@ +/******************************************************************************* + ** + ** smolbote: yet another qute browser + ** Copyright (C) 2017 Xian Nox + ** + ** This program 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. + ** + ** This program 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 . + ** + ******************************************************************************/ + +#include "profilesdialog.h" +#include "ui_profilesdialog.h" + +#include "browser.h" +#include + +ProfilesDialog::ProfilesDialog(MainWindow *window, QWidget *parent) : + QDialog(parent), + ui(new Ui::ProfilesDialog) +{ + ui->setupUi(this); + m_window = window; + + connect(this, SIGNAL(accepted()), this, SLOT(loadSelectedProfile())); +} + +ProfilesDialog::~ProfilesDialog() +{ + delete ui; +} + +int ProfilesDialog::exec() +{ + qDebug("Showing..."); + for(QString name : qApp->profiles()) { + ui->listWidget->addItem(name); + } + return QDialog::exec(); +} + +void ProfilesDialog::loadSelectedProfile() +{ + m_window->setProfile(qApp->profile(ui->listWidget->currentItem()->text())); +} diff --git a/src/forms/profilesdialog.h b/src/forms/profilesdialog.h new file mode 100644 index 0000000..bb6655b --- /dev/null +++ b/src/forms/profilesdialog.h @@ -0,0 +1,50 @@ +/******************************************************************************* + ** + ** smolbote: yet another qute browser + ** Copyright (C) 2017 Xian Nox + ** + ** This program 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. + ** + ** This program 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 . + ** + ******************************************************************************/ + +#ifndef PROFILESDIALOG_H +#define PROFILESDIALOG_H + +#include + +namespace Ui { +class ProfilesDialog; +} + +class MainWindow; +class ProfilesDialog : public QDialog +{ + Q_OBJECT + +public: + explicit ProfilesDialog(MainWindow *window, QWidget *parent = 0); + ~ProfilesDialog(); + +public slots: + int exec(); + +private slots: + void loadSelectedProfile(); + +private: + Ui::ProfilesDialog *ui; + MainWindow *m_window; +}; + +#endif // PROFILESDIALOG_H diff --git a/src/forms/profilesdialog.ui b/src/forms/profilesdialog.ui new file mode 100644 index 0000000..880e441 --- /dev/null +++ b/src/forms/profilesdialog.ui @@ -0,0 +1,74 @@ + + + ProfilesDialog + + + + 0 + 0 + 564 + 458 + + + + Dialog + + + + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + ProfilesDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + ProfilesDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/main.cpp b/src/main.cpp index 0e55a8f..e1f4c5c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,13 +26,15 @@ int main(int argc, char *argv[]) { Browser app(argc, argv); + app.setApplicationName("smolbote"); #ifdef GIT_VERSION app.setApplicationVersion(GIT_VERSION); #else app.setApplicationVersion("1.0.0"); #endif - app.setWindowIcon(QIcon(QLatin1String(":/icon.svg"))); + // This lets the web view automatically scale on high-dpi displays. + app.setAttribute(Qt::AA_EnableHighDpiScaling); QCommandLineParser parser; parser.setApplicationDescription("yet another Qt browser"); @@ -53,7 +55,7 @@ int main(int argc, char *argv[]) MainWindow *w = new MainWindow(parser.positionalArguments()); if(parser.isSet(profileOption)) { - w->loadProfile(parser.value(profileOption)); + w->setProfile(app.profile(parser.value(profileOption))); } app.addWindow(w); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 537c04f..79552d6 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -20,11 +20,9 @@ #include "mainwindow.h" #include "ui_mainwindow.h" -#include -#include +#include "widgets/mainwindowmenubar.h" #include #include "browser.h" -#include #include #include #include "forms/aboutdialog.h" @@ -54,39 +52,9 @@ MainWindow::MainWindow(QUrl defaultUrl, QWidget *parent) : setTabPosition(Qt::RightDockWidgetArea, QTabWidget::North); // Main menu - QMenuBar *menuBar = new QMenuBar(this); + MainWindowMenuBar *menuBar = new MainWindowMenuBar(this); menuBar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred); - // Browser menu - QMenu *browserMenu = new QMenu(qApp->applicationName(), menuBar); - menuBar->addMenu(browserMenu); - browserMenu->addAction(tr("New Window"), this, SLOT(handleNewWindow()), QKeySequence::fromString(sSettings->value("window.shortcuts.windowNew").toString())); - browserMenu->addAction(tr("New Tab"), this, SLOT(addNewTab()), QKeySequence::fromString(sSettings->value("window.shortcuts.tabNew").toString())); - browserMenu->addSeparator(); - browserMenu->addAction(tr("About"), this, SLOT(about()), QKeySequence(tr("F1"))); - browserMenu->addAction(tr("About Qt"), qApp, SLOT(aboutQt())); - browserMenu->addAction(tr("Quit"), qApp, SLOT(quit()), QKeySequence::fromString(sSettings->value("window.shortcuts.windowClose").toString())); - - // Tools menu - QMenu *toolsMenu = new QMenu(tr("Tools"), menuBar); - menuBar->addMenu(toolsMenu); - QAction *downloadsAction = toolsMenu->addAction(tr("Downloads"), Browser::instance()->downloads(), SLOT(show())); - downloadsAction->setParent(this); - downloadsAction->setShortcut(QKeySequence::fromString(sSettings->value("downloads.dialogShortcut").toString())); - QAction *bookmarksAction = toolsMenu->addAction(tr("Bookmarks"), Browser::instance()->bookmarks(), SLOT(show())); - bookmarksAction->setParent(this); - bookmarksAction->setShortcut(QKeySequence(sSettings->value("bookmarks.dialogShortcut").toString())); - toolsMenu->addSeparator(); - toolsMenu->addAction(tr("Blocker"), qApp->blocklists(), SLOT(show()), QKeySequence::fromString(sSettings->value("blocker.shortcut").toString())); - - // Profile menu - QMenu *profileMenu = new QMenu(tr("Profile"), menuBar); - menuBar->addMenu(profileMenu); - profileMenu->addAction(tr("View profile"), this, SLOT(profileAction())); - profileMenu->addAction(tr("Load profile"), this, SLOT(loadProfile())); - //profileMenu->addAction(tr("Settings")); - profileMenu->addAction(tr("Cookies"), this, SLOT(cookiesAction())); - // Add the toolbars // tabToolBar: main menu and tab list tabToolBar->setMovable(sSettings->value("window.ui.tabtoolbarMovable", true).toBool()); @@ -134,9 +102,9 @@ MainWindow::MainWindow(QUrl defaultUrl, QWidget *parent) : addAction(focusAddressAction); if(!defaultUrl.isEmpty()) { - addNewTab(defaultUrl); + newTab(defaultUrl); } else { - addNewTab(sSettings->value("general.homepage", QUrl("about:blank")).toUrl()); + newTab(sSettings->value("general.homepage", QUrl("about:blank")).toUrl()); } resize(sSettings->value("window.width", 800).toInt(), sSettings->value("window.height", 600).toInt()); @@ -150,7 +118,7 @@ MainWindow::MainWindow(const QStringList urlList, QWidget *parent) : { QStringList::const_iterator i; for(i = urlList.constBegin(); i != urlList.constEnd(); ++i) { - addNewTab(QUrl::fromUserInput(*i)); + newTab(QUrl::fromUserInput(*i)); } } @@ -177,7 +145,7 @@ void MainWindow::addTabbedDock(Qt::DockWidgetArea area, QDockWidget *widget) } } -void MainWindow::addNewTab(const QUrl &url) +void MainWindow::newTab(const QUrl &url) { if(!url.isEmpty()) { tabBar->addTab(m_profile, url); @@ -210,19 +178,9 @@ void MainWindow::about() dlg->exec(); } -void MainWindow::loadProfile(const QString name) +void MainWindow::setProfile(WebEngineProfile *profile) { - if(name.isEmpty()) { - bool ok; - QString _name = QInputDialog::getText(this, tr("Load Profile"), tr("Enter Profile name"), QLineEdit::Normal, QString(""), &ok); - if(ok) { - m_profile = qApp->profile(_name); - } else { - return; - } - } else { - m_profile = qApp->profile(name); - } + m_profile = profile; tabBar->setProfile(m_profile); } @@ -235,7 +193,7 @@ void MainWindow::toggleFullscreen() } } -void MainWindow::handleNewWindow(const QUrl &url) +void MainWindow::newWindow(const QUrl &url) { Browser::instance()->addWindow(new MainWindow(url)); } diff --git a/src/mainwindow.h b/src/mainwindow.h index ed54461..a1cbcc0 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -48,10 +48,15 @@ public: void addTabbedDock(Qt::DockWidgetArea area, QDockWidget *widget); public slots: - void addNewTab(const QUrl &url = QUrl("")); - void focusAddress(); + void about(); + + void newTab(const QUrl &url = QUrl("")); + void newWindow(const QUrl &url = QUrl("")); + + void profileAction(); + void cookiesAction(); - void loadProfile(const QString name = ""); + void setProfile(WebEngineProfile *profile); void toggleFullscreen(); @@ -59,12 +64,7 @@ protected: void closeEvent(QCloseEvent *event) override; private slots: - void about(); - - void profileAction(); - void cookiesAction(); - - void handleNewWindow(const QUrl &url = QUrl("")); + void focusAddress(); void handleTabChanged(WebView *view); void handleUrlChanged(); void handleTitleUpdated(const QString &title); diff --git a/src/webengine/webengineprofile.cpp b/src/webengine/webengineprofile.cpp index 814d38c..89cc301 100644 --- a/src/webengine/webengineprofile.cpp +++ b/src/webengine/webengineprofile.cpp @@ -27,8 +27,6 @@ WebEngineProfile::WebEngineProfile(QObject *parent) : QWebEngineProfile(parent) { // Off-the-record constructor - - m_profileDialog = new ProfileDialog(this); } WebEngineProfile::WebEngineProfile(const QString &storageName, QObject *parent) : @@ -37,8 +35,6 @@ WebEngineProfile::WebEngineProfile(const QString &storageName, QObject *parent) setPersistentStoragePath(sSettings->value("browser.profile.path").toString() + storageName); setCachePath(sSettings->value("browser.profile.path").toString() + storageName); - m_profileDialog = new ProfileDialog(this); - QString profilePath = persistentStoragePath() + "/profile.ini"; qDebug("Reading profile from [%s]", qUtf8Printable(profilePath)); QSettings config(profilePath, QSettings::IniFormat); @@ -110,10 +106,16 @@ WebEngineProfile::~WebEngineProfile() if(!isOffTheRecord()) { saveProfile(); } + if(m_profileDialog != nullptr) { + m_profileDialog->deleteLater(); + } } ProfileDialog *WebEngineProfile::dialog() { + if(m_profileDialog == nullptr) { + m_profileDialog = new ProfileDialog(this); + } return m_profileDialog; } diff --git a/src/webengine/webengineprofile.h b/src/webengine/webengineprofile.h index dfdd0f8..4b36940 100644 --- a/src/webengine/webengineprofile.h +++ b/src/webengine/webengineprofile.h @@ -41,7 +41,7 @@ public slots: void saveProfile(); private: - ProfileDialog *m_profileDialog; + ProfileDialog *m_profileDialog = nullptr; }; #endif // WEBENGINEPROFILE_H diff --git a/src/widgets/mainwindowmenubar.cpp b/src/widgets/mainwindowmenubar.cpp new file mode 100644 index 0000000..a3ec497 --- /dev/null +++ b/src/widgets/mainwindowmenubar.cpp @@ -0,0 +1,83 @@ +/******************************************************************************* + ** + ** smolbote: yet another qute browser + ** Copyright (C) 2017 Xian Nox + ** + ** This program 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. + ** + ** This program 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 . + ** + ******************************************************************************/ + +#include "mainwindowmenubar.h" +#include +#include "browser.h" +#include +#include "forms/profilesdialog.h" + +MainWindowMenuBar::MainWindowMenuBar(MainWindow *parent) : + QMenuBar(parent) +{ + m_parentWindow = parent; + + // Browser menu + QMenu *browserMenu = new QMenu(qApp->applicationName(), this); + addMenu(browserMenu); + browserMenu->addAction(tr("New Window"), parent, SLOT(newWindow()), QKeySequence::fromString(sSettings->value("window.shortcuts.windowNew").toString())); + browserMenu->addAction(tr("New Tab"), parent, SLOT(newTab()), QKeySequence::fromString(sSettings->value("window.shortcuts.tabNew").toString())); + browserMenu->addSeparator(); + browserMenu->addAction(tr("About"), parent, SLOT(about()), QKeySequence(tr("F1"))); + browserMenu->addAction(tr("About Qt"), qApp, SLOT(aboutQt())); + browserMenu->addSeparator(); + browserMenu->addAction(tr("Quit"), qApp, SLOT(quit()), QKeySequence::fromString(sSettings->value("window.shortcuts.windowClose").toString())); + + // Tools menu + QMenu *toolsMenu = new QMenu(tr("Tools"), this); + addMenu(toolsMenu); + QAction *downloadsAction = toolsMenu->addAction(tr("Downloads"), Browser::instance()->downloads(), SLOT(show())); + downloadsAction->setParent(parent); + downloadsAction->setShortcut(QKeySequence::fromString(sSettings->value("downloads.dialogShortcut").toString())); + QAction *bookmarksAction = toolsMenu->addAction(tr("Bookmarks"), Browser::instance()->bookmarks(), SLOT(show())); + bookmarksAction->setParent(parent); + bookmarksAction->setShortcut(QKeySequence(sSettings->value("bookmarks.dialogShortcut").toString())); + toolsMenu->addSeparator(); + toolsMenu->addAction(tr("Filter"), qApp->blocklists(), SLOT(show()), QKeySequence::fromString(sSettings->value("blocker.shortcut").toString())); + + // Profile menu + QMenu *profileMenu = new QMenu(tr("Profile"), this); + addMenu(profileMenu); + profileMenu->addAction(tr("Profiles"), this, SLOT(handleLoadProfile())); + profileMenu->addSeparator(); + profileMenu->addAction(tr("View profile"), parent, SLOT(profileAction())); + profileMenu->addAction(tr("Settings")); + profileMenu->addAction(tr("Cookies"), parent, SLOT(cookiesAction())); + + // Page menu + QMenu *pageMenu = new QMenu(tr("Page"), this); + addMenu(pageMenu); + pageMenu->addAction(tr("Print")); + pageMenu->addAction(tr("Print to PDF")); + pageMenu->addAction(tr("Zoom")); + +} + +void MainWindowMenuBar::handleLoadProfile() +{ + ProfilesDialog *dlg = new ProfilesDialog(m_parentWindow, this); + dlg->exec(); + +// bool ok; +// QString _name = QInputDialog::getText(this, tr("Load Profile"), tr("Enter Profile name"), QLineEdit::Normal, QString(""), &ok); +// if(ok) { +// m_parentWindow->setProfile(qApp->profile(_name)); +// } +} diff --git a/src/widgets/mainwindowmenubar.h b/src/widgets/mainwindowmenubar.h new file mode 100644 index 0000000..a6c6dc4 --- /dev/null +++ b/src/widgets/mainwindowmenubar.h @@ -0,0 +1,40 @@ +/******************************************************************************* + ** + ** smolbote: yet another qute browser + ** Copyright (C) 2017 Xian Nox + ** + ** This program 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. + ** + ** This program 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 . + ** + ******************************************************************************/ + +#ifndef MAINWINDOWMENUBAR_H +#define MAINWINDOWMENUBAR_H + +#include + +class MainWindow; +class MainWindowMenuBar : public QMenuBar +{ + Q_OBJECT +public: + explicit MainWindowMenuBar(MainWindow *parent = nullptr); + +private slots: + void handleLoadProfile(); + +private: + MainWindow *m_parentWindow; +}; + +#endif // MAINWINDOWMENUBAR_H -- cgit v1.2.1