diff --git a/companion/releasenotes.txt b/companion/releasenotes.txt deleted file mode 100644 index 58ef7c750..000000000 --- a/companion/releasenotes.txt +++ /dev/null @@ -1,484 +0,0 @@ -

Version 2.2.1 / 2017-12-17

- -Please see this page for details. - -

Version 2.2.0 / 2017-05-30

- -Major release! Please see this page for details. - -

Version 2.1.9 / 2016-09-14

- - - - -

Version 2.1.8 / 2016-04-14

- - - - -

Version 2.1.7 / 2016-01-04

- - - - -

Version 2.1.6 / 2015-11-11

- - - - -

Version 2.1.5 / 2015-11-05

- -Notice: version 2.1.4 was skipped by the OpenTX team to avoid confusion with FrSky's release of OpenTX 2.1.4 - - - - -

Version 2.1.3 / 2015-09-09

- - - - -

Version 2.1.2 / 2015-09-07

- - - - -

Version 2.1.1 / 2015-08-06

- - - -

Version 2.1.0 / 2015-07-16

- - - -

Version 2.0.17 / 2015-05-04

- - - -

Version 2.0.16 / 2015-05-03

- - - -

Version 2.0.15 / 2015-01-13

- - -

Version 2.0.14 / 2015-01-12

- - -

Version 2.0.13 / 2014-11-20

- - -

Version 2.0.12 / 2014-09-15

- - -

Version 2.0.11 / 2014-09-10

- - -

Version 2.0.10 / 2014-09-08

- - -

Version 2.0.8 / 2014-07-23

- - -

Version 2.0.7

- - -

Version 2.0.6

- - -

Version 2.0.5

- - -

Version 2.0.4

- - -

Version 2.0.3

- - -

Version 2.0.2

- - -

Version 2.0.1

- - -

Version 2.0.0

- - -

Version 1.52

- - -

Version 1.51

- - -

Version 1.50

- - -

Version 1.49

- - -

Version 1.48

- - -

Version 1.47

- - -

Version 1.46

- - -

Version 1.45

- - -

Version 1.44

- - -

Version 1.43

- - -

Version 1.42

- - -

Version 1.41

- - -

Version 1.40

- - -

Version 1.39

- - -

Version 1.38

- - -

Version 1.37

- - -

Version 1.36

- - -

Version 1.35

- diff --git a/companion/src/companion.qrc b/companion/src/companion.qrc index b78cf3506..bd395a443 100644 --- a/companion/src/companion.qrc +++ b/companion/src/companion.qrc @@ -2,7 +2,6 @@ images/customize.png images/icon.png - ../releasenotes.txt images/screenshot.png images/splash.png images/companion-title.png @@ -191,6 +190,8 @@ themes/monochrome/16/stop.png themes/monochrome/16/write_eeprom.png themes/monochrome/16/sdsync.png + themes/monochrome/16/folder-tree-read.png + themes/monochrome/16/folder-tree-write.png themes/monochrome/24/paintbrush.png themes/monochrome/24/open.png themes/monochrome/24/edit.png @@ -235,6 +236,8 @@ themes/monochrome/24/stop.png themes/monochrome/24/write_eeprom.png themes/monochrome/24/sdsync.png + themes/monochrome/24/folder-tree-read.png + themes/monochrome/24/folder-tree-write.png themes/monochrome/32/paintbrush.png themes/monochrome/32/open.png themes/monochrome/32/edit.png @@ -279,6 +282,8 @@ themes/monochrome/32/stop.png themes/monochrome/32/write_eeprom.png themes/monochrome/32/sdsync.png + themes/monochrome/32/folder-tree-read.png + themes/monochrome/32/folder-tree-write.png themes/monochrome/48/paintbrush.png themes/monochrome/48/open.png themes/monochrome/48/edit.png @@ -323,6 +328,8 @@ themes/monochrome/48/stop.png themes/monochrome/48/write_eeprom.png themes/monochrome/48/sdsync.png + themes/monochrome/48/folder-tree-read.png + themes/monochrome/48/folder-tree-write.png themes/classic/16/paintbrush.png themes/classic/16/open.png themes/classic/16/edit.png @@ -367,6 +374,8 @@ themes/classic/16/stop.png themes/classic/16/write_eeprom.png themes/classic/16/sdsync.png + themes/classic/16/folder-tree-read.png + themes/classic/16/folder-tree-write.png themes/classic/24/paintbrush.png themes/classic/24/open.png themes/classic/24/edit.png @@ -411,6 +420,8 @@ themes/classic/24/stop.png themes/classic/24/write_eeprom.png themes/classic/24/sdsync.png + themes/classic/24/folder-tree-read.png + themes/classic/24/folder-tree-write.png themes/classic/32/paintbrush.png themes/classic/32/open.png themes/classic/32/edit.png @@ -455,6 +466,8 @@ themes/classic/32/stop.png themes/classic/32/write_eeprom.png themes/classic/32/sdsync.png + themes/classic/32/folder-tree-read.png + themes/classic/32/folder-tree-write.png themes/classic/48/paintbrush.png themes/classic/48/open.png themes/classic/48/edit.png @@ -499,6 +512,8 @@ themes/classic/48/stop.png themes/classic/48/write_eeprom.png themes/classic/48/sdsync.png + themes/classic/48/folder-tree-read.png + themes/classic/48/folder-tree-write.png themes/monoblue/16/paintbrush.png themes/monoblue/16/open.png themes/monoblue/16/edit.png @@ -543,6 +558,8 @@ themes/monoblue/16/stop.png themes/monoblue/16/write_eeprom.png themes/monoblue/16/sdsync.png + themes/monoblue/16/folder-tree-read.png + themes/monoblue/16/folder-tree-write.png themes/monoblue/24/paintbrush.png themes/monoblue/24/open.png themes/monoblue/24/edit.png @@ -587,6 +604,8 @@ themes/monoblue/24/stop.png themes/monoblue/24/write_eeprom.png themes/monoblue/24/sdsync.png + themes/monoblue/24/folder-tree-read.png + themes/monoblue/24/folder-tree-write.png themes/monoblue/32/paintbrush.png themes/monoblue/32/open.png themes/monoblue/32/edit.png @@ -631,6 +650,8 @@ themes/monoblue/32/stop.png themes/monoblue/32/write_eeprom.png themes/monoblue/32/sdsync.png + themes/monoblue/32/folder-tree-read.png + themes/monoblue/32/folder-tree-write.png themes/monoblue/48/paintbrush.png themes/monoblue/48/open.png themes/monoblue/48/edit.png @@ -675,6 +696,8 @@ themes/monoblue/48/stop.png themes/monoblue/48/write_eeprom.png themes/monoblue/48/sdsync.png + themes/monoblue/48/folder-tree-read.png + themes/monoblue/48/folder-tree-write.png themes/monowhite/16/paintbrush.png themes/monowhite/16/open.png themes/monowhite/16/edit.png @@ -719,6 +742,8 @@ themes/monowhite/16/stop.png themes/monowhite/16/write_eeprom.png themes/monowhite/16/sdsync.png + themes/monowhite/16/folder-tree-read.png + themes/monowhite/16/folder-tree-write.png themes/monowhite/24/paintbrush.png themes/monowhite/24/open.png themes/monowhite/24/edit.png @@ -763,6 +788,8 @@ themes/monowhite/24/stop.png themes/monowhite/24/write_eeprom.png themes/monowhite/24/sdsync.png + themes/monowhite/24/folder-tree-read.png + themes/monowhite/24/folder-tree-write.png themes/monowhite/32/paintbrush.png themes/monowhite/32/open.png themes/monowhite/32/edit.png @@ -807,6 +834,8 @@ themes/monowhite/32/stop.png themes/monowhite/32/write_eeprom.png themes/monowhite/32/sdsync.png + themes/monowhite/32/folder-tree-read.png + themes/monowhite/32/folder-tree-write.png themes/monowhite/48/paintbrush.png themes/monowhite/48/open.png themes/monowhite/48/edit.png @@ -851,6 +880,8 @@ themes/monowhite/48/stop.png themes/monowhite/48/write_eeprom.png themes/monowhite/48/sdsync.png + themes/monowhite/48/folder-tree-read.png + themes/monowhite/48/folder-tree-write.png themes/yerico/16/paintbrush.png themes/yerico/16/open.png themes/yerico/16/edit.png @@ -895,6 +926,8 @@ themes/yerico/16/stop.png themes/yerico/16/write_eeprom.png themes/yerico/16/sdsync.png + themes/yerico/16/folder-tree-read.png + themes/yerico/16/folder-tree-write.png themes/yerico/24/paintbrush.png themes/yerico/24/open.png themes/yerico/24/edit.png @@ -939,6 +972,8 @@ themes/yerico/24/stop.png themes/yerico/24/write_eeprom.png themes/yerico/24/sdsync.png + themes/yerico/24/folder-tree-read.png + themes/yerico/24/folder-tree-write.png themes/yerico/32/paintbrush.png themes/yerico/32/open.png themes/yerico/32/edit.png @@ -983,6 +1018,8 @@ themes/yerico/32/stop.png themes/yerico/32/write_eeprom.png themes/yerico/32/sdsync.png + themes/yerico/32/folder-tree-read.png + themes/yerico/32/folder-tree-write.png themes/yerico/48/paintbrush.png themes/yerico/48/open.png themes/yerico/48/edit.png @@ -1027,6 +1064,8 @@ themes/yerico/48/stop.png themes/yerico/48/write_eeprom.png themes/yerico/48/sdsync.png + themes/yerico/48/folder-tree-read.png + themes/yerico/48/folder-tree-write.png sounds/0.wav sounds/1.wav sounds/2.wav diff --git a/companion/src/images/originals/folder-tree-read-classic.svg b/companion/src/images/originals/folder-tree-read-classic.svg new file mode 100644 index 000000000..99bdf8f32 --- /dev/null +++ b/companion/src/images/originals/folder-tree-read-classic.svg @@ -0,0 +1,162 @@ + + + + diff --git a/companion/src/images/originals/folder-tree-read-monochrome.svg b/companion/src/images/originals/folder-tree-read-monochrome.svg new file mode 100644 index 000000000..61bbd4967 --- /dev/null +++ b/companion/src/images/originals/folder-tree-read-monochrome.svg @@ -0,0 +1,66 @@ + + + + diff --git a/companion/src/images/originals/folder-tree-read-outline.svg b/companion/src/images/originals/folder-tree-read-outline.svg new file mode 100644 index 000000000..4411f60e4 --- /dev/null +++ b/companion/src/images/originals/folder-tree-read-outline.svg @@ -0,0 +1,110 @@ + + + + diff --git a/companion/src/images/originals/folder-tree-read-yerico.svg b/companion/src/images/originals/folder-tree-read-yerico.svg new file mode 100644 index 000000000..9128da187 --- /dev/null +++ b/companion/src/images/originals/folder-tree-read-yerico.svg @@ -0,0 +1,111 @@ + + + + diff --git a/companion/src/images/originals/folder-tree-write-classic.svg b/companion/src/images/originals/folder-tree-write-classic.svg new file mode 100644 index 000000000..c1fcb7a5a --- /dev/null +++ b/companion/src/images/originals/folder-tree-write-classic.svg @@ -0,0 +1,162 @@ + + + + diff --git a/companion/src/images/originals/folder-tree-write-monochrome.svg b/companion/src/images/originals/folder-tree-write-monochrome.svg new file mode 100644 index 000000000..1ef1dac65 --- /dev/null +++ b/companion/src/images/originals/folder-tree-write-monochrome.svg @@ -0,0 +1,66 @@ + + + + diff --git a/companion/src/images/originals/folder-tree-write-outline.svg b/companion/src/images/originals/folder-tree-write-outline.svg new file mode 100644 index 000000000..e9a703d9d --- /dev/null +++ b/companion/src/images/originals/folder-tree-write-outline.svg @@ -0,0 +1,108 @@ + + + + diff --git a/companion/src/images/originals/folder-tree-write-yerico.svg b/companion/src/images/originals/folder-tree-write-yerico.svg new file mode 100644 index 000000000..4318c5ea2 --- /dev/null +++ b/companion/src/images/originals/folder-tree-write-yerico.svg @@ -0,0 +1,111 @@ + + + + diff --git a/companion/src/mainwindow.cpp b/companion/src/mainwindow.cpp index 542b15d73..362bed837 100644 --- a/companion/src/mainwindow.cpp +++ b/companion/src/mainwindow.cpp @@ -90,7 +90,7 @@ MainWindow::MainWindow(): if (g.isFirstUse()) { g.warningId(g.warningId() | AppMessages::MSG_WELCOME); - QTimer::singleShot(updateDelay-500, this, SLOT(appPrefs())); // must be shown before warnings dialog but after splash + QTimer::singleShot(updateDelay-500, this, SLOT(editAppSettings())); // must be shown before warnings dialog but after splash } else { if (!g.previousVersion().isEmpty()) @@ -205,7 +205,7 @@ void MainWindow::closeEvent(QCloseEvent *event) #endif g.mainWinGeo(saveGeometry()); g.mainWinState(saveState()); - g.tabbedMdi(actTabbedWindows->isChecked()); + g.tabbedMdi(tabbedWindowsAct->isChecked()); QApplication::closeAllWindows(); mdiArea->closeAllSubWindows(); if (mdiArea->currentSubWindow()) { @@ -255,7 +255,7 @@ void MainWindow::manualCheckForUpdates() statusBar()->clearMessage(); } -void MainWindow::downloads() +void MainWindow::updates() { doUpdates(false); } @@ -325,13 +325,13 @@ void MainWindow::onIconSizeChanged(QAction * act) void MainWindow::setTabbedWindows(bool on) { mdiArea->setViewMode(on ? QMdiArea::TabbedView : QMdiArea::SubWindowView); - if (actTileWindows) - actTileWindows->setDisabled(on); - if (actCascadeWindows) - actCascadeWindows->setDisabled(on); + if (tileWindowsAct) + tileWindowsAct->setDisabled(on); + if (cascadeWindowsAct) + cascadeWindowsAct->setDisabled(on); - if (actTabbedWindows->isChecked() != on) - actTabbedWindows->setChecked(on); + if (tabbedWindowsAct->isChecked() != on) + tabbedWindowsAct->setChecked(on); } void MainWindow::newFile() @@ -452,7 +452,7 @@ void MainWindow::loadProfile() } } -void MainWindow::appPrefs() +void MainWindow::editAppSettings() { AppPreferencesDialog * dialog = new AppPreferencesDialog(this, updateFactories); dialog->setMainWinHasDirtyChild(anyChildrenDirty()); @@ -460,6 +460,7 @@ void MainWindow::appPrefs() connect(dialog, &AppPreferencesDialog::firmwareProfileChanged, this, &MainWindow::onCurrentProfileChanged); dialog->exec(); dialog->deleteLater(); + updateMenus(); } void MainWindow::sdsync(bool postUpdate) @@ -677,9 +678,11 @@ void MainWindow::updateMenus() compareAct->setEnabled(activeChild); writeSettingsAct->setEnabled(activeChild); readSettingsAct->setEnabled(true); + writeSettingsSDPathAct->setEnabled(activeChild && isSDPathValid()); + readSettingsSDPathAct->setEnabled(isSDPathValid()); writeBUToRadioAct->setEnabled(false); readBUToFileAct->setEnabled(false); - editSplashAct->setDisabled(IS_FAMILY_HORUS_OR_T16(getCurrentBoard())); + editSplashAct->setDisabled(Boards::getBoardCapability(getCurrentBoard(), Board::HasColorLcd)); foreach (QAction * act, fileWindowActions) { if (!act) @@ -692,34 +695,39 @@ void MainWindow::updateMenus() if (act->isSeparator() && act->parent() == this) delete act; } - fileWindowActions.clear(); - if (activeChild) { - editMenu->clear(); - editMenu->addActions(activeMdiChild()->getEditActions()); - editMenu->addSeparator(); - editMenu->addActions(activeMdiChild()->getModelActions()); // maybe separate menu/toolbar? - editMenu->setEnabled(true); - editToolBar->clear(); - editToolBar->addActions(activeMdiChild()->getEditActions()); - editToolBar->setEnabled(true); + fileWindowActions.clear(); + + if (activeChild) { + modelsMenu->clear(); + modelsMenu->addActions(activeMdiChild()->getEditActions()); + modelsMenu->addSeparator(); + modelsMenu->addActions(activeMdiChild()->getModelActions()); // maybe separate menu/toolbar? + modelsMenu->addAction(compareAct); + modelsMenu->setEnabled(true); + + modelsToolBar->clear(); + modelsToolBar->addActions(activeMdiChild()->getEditActions()); + modelsToolBar->addAction(compareAct); + modelsToolBar->setEnabled(true); + if (activeMdiChild()->getAction(MdiChild::ACT_MDL_MOV)) { // workaround for default split button appearance of action with menu :-/ QToolButton * btn; - if ((btn = qobject_cast(editToolBar->widgetForAction(activeMdiChild()->getAction(MdiChild::ACT_MDL_MOV))))) + if ((btn = qobject_cast(modelsToolBar->widgetForAction(activeMdiChild()->getAction(MdiChild::ACT_MDL_MOV))))) btn->setPopupMode(QToolButton::InstantPopup); } fileWindowActions = activeMdiChild()->getGeneralActions(); QAction *sep = new QAction(this); sep->setSeparator(true); - fileWindowActions.append(sep); - fileMenu->insertActions(logsAct, fileWindowActions); - fileToolBar->insertActions(logsAct, fileWindowActions); + fileWindowActions.insert(0, sep); + radioMenu->addActions(fileWindowActions); + modelsToolBar->addActions(fileWindowActions); // do not put these in radio toolbar } else { - editToolBar->setDisabled(true); - editMenu->setDisabled(true); + modelsToolBar->setDisabled(true); + modelsMenu->setDisabled(true); } foreach (QAction * act, windowsListActions->actions()) { @@ -732,7 +740,7 @@ void MainWindow::updateMenus() updateRecentFileActions(); updateProfilesActions(); - setWindowTitle(tr("EdgeTX Companion %1 - Radio: %2 - Profile: %3").arg(VERSION).arg(getCurrentFirmware()->getName()).arg(g.profile[g.id()].name())); + setWindowTitle(tr("%1 %2 - Radio: %3 - Profile: %4").arg(CPN_STR_APP_NAME).arg(VERSION).arg(getCurrentFirmware()->getName()).arg(g.profile[g.id()].name())); } MdiChild * MainWindow::createMdiChild() @@ -801,59 +809,70 @@ void MainWindow::trAct(QAction * act, const QString & text, const QString & desc void MainWindow::retranslateUi(bool showMsg) { - trAct(newAct, tr("New"), tr("Create a new Models and Settings file")); - trAct(openAct, tr("Open..."), tr("Open Models and Settings file")); - trAct(saveAct, tr("Save"), tr("Save Models and Settings file")); - trAct(saveAsAct, tr("Save As..."), tr("Save Models and Settings file")); - trAct(closeAct, tr("Close"), tr("Close Models and Settings file")); - trAct(exitAct, tr("Exit"), tr("Exit the application")); - trAct(aboutAct, tr("About Companion..."), tr("Show the application's About box")); + trAct(newAct, tr("New"), tr("Create a new Models and Settings file")); + trAct(openAct, tr("Open..."), tr("Open an existing Models and Settings file")); + trAct(saveAct, tr("Save"), tr("Save to Models and Settings file")); + trAct(saveAsAct, tr("Save As..."), tr("Save Models and Settings to another file name")); + trAct(closeAct, tr("Close"), tr("Close Models and Settings file")); + trAct(recentFilesAct, tr("Recent Files"), tr("List of recently used files")); + trAct(writeSettingsSDPathAct, tr("Write Models and Settings to SD Path"), tr("Write Models and Settings to SD Path")); + trAct(readSettingsSDPathAct, tr("Read Models and Settings from SD Path"), tr("Read Models and Settings from SD Path")); + trAct(exitAct, tr("Exit"), tr("Exit the application")); - trAct(recentFilesAct, tr("Recent Files"), tr("List of recently used files")); - trAct(profilesMenuAct, tr("Radio Profiles"), tr("Create or Select Radio Profiles")); - trAct(logsAct, tr("View Log File..."), tr("Open and view log file")); - trAct(appPrefsAct, tr("Settings..."), tr("Edit Settings")); - trAct(downloadsAct, tr("Download components..."), tr("Download EdgeTX components and supporting resources")); - trAct(manualChkForUpdAct, tr("Check for updates..."), tr("Check for updates to EdgeTX and supporting resources")); - trAct(changelogAct, tr("Release notes..."), tr("Show release notes")); - trAct(compareAct, tr("Compare Models..."), tr("Compare models")); - trAct(editSplashAct, tr("Edit Radio Splash Image..."), tr("Edit the splash image of your Radio")); - trAct(readFlashAct, tr("Read Firmware from Radio"), tr("Read firmware from Radio")); - trAct(writeFlashAct, tr("Write Firmware to Radio"), tr("Write firmware to Radio")); - trAct(sdsyncAct, tr("Synchronize SD"), tr("SD card synchronization")); + trAct(editAppSettingsAct, tr("Edit Settings..."), tr("Edit %1 and Simulator settings (including radio profiles) settings").arg(CPN_STR_APP_NAME)); + trAct(exportAppSettingsAct, tr("Export Settings..."), tr("Save all the current %1 and Simulator settings (including radio profiles) to a file.").arg(CPN_STR_APP_NAME)); + trAct(importAppSettingsAct, tr("Import Settings..."), tr("Load %1 and Simulator settings from a prevously exported settings file.").arg(CPN_STR_APP_NAME)); - //trAct(openDocURLAct, tr("Manuals and other Documents"), tr("Open the EdgeTX document page in a web browser")); - trAct(writeSettingsAct, tr("Write Models and Settings To Radio"), tr("Write Models and Settings to Radio")); - trAct(readSettingsAct, tr("Read Models and Settings From Radio"), tr("Read Models and Settings from Radio")); - trAct(burnConfigAct, tr("Configure Communications..."), tr("Configure software for communicating with the Radio")); + trAct(burnConfigAct, tr("Configure Radio Communications..."), tr("Configure Companion for communicating with the Radio")); + trAct(editSplashAct, tr("Edit Radio Splash Image..."), tr("Edit the splash image of your Radio")); + trAct(readFlashAct, tr("Read Firmware from Radio"), tr("Read firmware from Radio")); + trAct(writeFlashAct, tr("Write Firmware to Radio"), tr("Write firmware to Radio")); + trAct(writeSettingsAct, tr("Write Models and Settings to Radio"), tr("Write Models and Settings to Radio")); + trAct(readSettingsAct, tr("Read Models and Settings from Radio"), tr("Read Models and Settings from Radio")); trAct(writeBUToRadioAct, tr("Write Backup to Radio"), tr("Write Backup from file to Radio")); trAct(readBUToFileAct, tr("Backup Radio to File"), tr("Save a complete backup file of all settings and model data in the Radio")); + trAct(compareAct, tr("Compare Models"), tr("Compare models")); + trAct(updatesAct, tr("Update components..."), tr("Download and update EdgeTX components and supporting resources")); + trAct(sdsyncAct, tr("Synchronize SD card..."), tr("SD card synchronization")); + trAct(logsAct, tr("View Log File..."), tr("Open and view log file")); + + trAct(profilesMenuAct, tr("Radio Profiles"), tr("Create or Select Radio Profiles")); trAct(createProfileAct, tr("Add Radio Profile"), tr("Create a new Radio Settings Profile")); trAct(copyProfileAct, tr("Copy Current Radio Profile"), tr("Duplicate current Radio Settings Profile")); trAct(deleteProfileAct, tr("Delete Current Radio Profile..."), tr("Delete the current Radio Settings Profile")); - trAct(exportSettingsAct, tr("Export Application Settings.."), tr("Save all the current %1 and Simulator settings (including radio profiles) to a file.").arg(CPN_STR_APP_NAME)); - trAct(importSettingsAct, tr("Import Application Settings.."), tr("Load %1 and Simulator settings from a prevously exported settings file.").arg(CPN_STR_APP_NAME)); + trAct(viewFileToolbarAct, tr("File Toolbar"), tr("Configure File toolbar visibility")); + trAct(viewModelsToolbarAct, tr("Models Toolbar"), tr("Configure Models toolbar visibility")); + trAct(viewRadioToolbarAct, tr("Radio Toolbar"), tr("Configure Radio toolbar visibility")); + trAct(viewSettingsToolbarAct, tr("Settings Toolbar"), tr("Configure Settings toolbar visibility")); + trAct(viewToolsToolbarAct, tr("Tools Toolbar"), tr("Configure Tools toolbar visibility")); - trAct(actTabbedWindows, tr("Tabbed Windows"), tr("Use tabs to arrange open windows.")); - trAct(actTileWindows, tr("Tile Windows"), tr("Arrange open windows across all the available space.")); - trAct(actCascadeWindows, tr("Cascade Windows"), tr("Arrange all open windows in a stack.")); - trAct(actCloseAllWindows, tr("Close All Windows"), tr("Closes all open files (prompts to save if necessary.")); + trAct(tabbedWindowsAct, tr("Tabbed Windows"), tr("Use tabs to arrange open windows.")); + trAct(tileWindowsAct, tr("Tile Windows"), tr("Arrange open windows across all the available space.")); + trAct(cascadeWindowsAct, tr("Cascade Windows"), tr("Arrange all open windows in a stack.")); + trAct(closeAllWindowsAct, tr("Close All Windows"), tr("Closes all open files (prompts to save if necessary.")); + + trAct(manualChkForUpdAct, tr("Check for updates..."), tr("Check for updates to EdgeTX and supporting resources")); + trAct(changelogAct, tr("Release notes..."), tr("Show release notes")); + trAct(aboutAct, tr("About"), tr("Show the application's About box")); - editMenu->setTitle(tr("Edit")); fileMenu->setTitle(tr("File")); + viewMenu->setTitle(tr("View")); + modelsMenu->setTitle(tr("Models")); settingsMenu->setTitle(tr("Settings")); themeMenu->setTitle(tr("Set Icon Theme")); iconThemeSizeMenu->setTitle(tr("Set Icon Size")); - burnMenu->setTitle(tr("Read/Write")); + radioMenu->setTitle(tr("Radio")); + toolsMenu->setTitle(tr("Tools")); windowMenu->setTitle(tr("Window")); helpMenu->setTitle(tr("Help")); fileToolBar->setWindowTitle(tr("File")); - editToolBar->setWindowTitle(tr("Edit")); - burnToolBar->setWindowTitle(tr("Write")); - helpToolBar->setWindowTitle(tr("Help")); + modelsToolBar->setWindowTitle(tr("Models")); + radioToolBar->setWindowTitle(tr("Radio")); + settingsToolBar->setWindowTitle(tr("Settings")); + toolsToolBar->setWindowTitle(tr("Tools")); showReadyStatus(); @@ -863,60 +882,71 @@ void MainWindow::retranslateUi(bool showMsg) void MainWindow::createActions() { - newAct = addAct("new.png", SLOT(newFile()), QKeySequence::New); - openAct = addAct("open.png", SLOT(openFile()), QKeySequence::Open); - saveAct = addAct("save.png", SLOT(save()), QKeySequence::Save); - saveAsAct = addAct("saveas.png", SLOT(saveAs()), tr("Ctrl+Shift+S")); // Windows doesn't have "native" save-as key, Lin/OSX both use this one anyway - closeAct = addAct("clear.png", SLOT(closeFile()) /*, QKeySequence::Close*/); // setting/showing this shortcut interferes with the system one (Ctrl+W/Ctrl-F4) - exitAct = addAct("exit.png", SLOT(closeAllWindows()), QKeySequence::Quit, qApp); + newAct = addAct("new.png", SLOT(newFile()), QKeySequence::New); + openAct = addAct("open.png", SLOT(openFile()), QKeySequence::Open); + saveAct = addAct("save.png", SLOT(save()), QKeySequence::Save); + saveAsAct = addAct("saveas.png", SLOT(saveAs()), tr("Ctrl+Shift+S")); // Windows doesn't have "native" save-as key, Lin/OSX both use this one anyway + // assigned menus in createMenus() + recentFilesAct = addAct("recentdocument.png"); + closeAct = addAct("clear.png", SLOT(closeFile()) /*, QKeySequence::Close*/); // setting/showing this shortcut interferes with the system one (Ctrl+W/Ctrl-F4) + // TODO change to more appropriate icon sets and uncomment toolbar actions + writeSettingsSDPathAct = addAct("folder-tree-write.png", SLOT(writeSettingsSDPath())); + readSettingsSDPathAct = addAct("folder-tree-read.png", SLOT(readSettingsSDPath())); + // end TODO + exitAct = addAct("exit.png", SLOT(closeAllWindows()), QKeySequence::Quit, qApp); - logsAct = addAct("logs.png", SLOT(logFile()), tr("Ctrl+Alt+L")); - appPrefsAct = addAct("apppreferences.png", SLOT(appPrefs()), QKeySequence::Preferences); - downloadsAct = addAct("download.png", SLOT(downloads()), tr("Ctrl+Alt+D")); - compareAct = addAct("compare.png", SLOT(compare()), tr("Ctrl+Alt+R")); - sdsyncAct = addAct("sdsync.png", SLOT(sdsync())); + editAppSettingsAct = addAct("apppreferences.png", SLOT(editAppSettings()), QKeySequence::Preferences); + exportAppSettingsAct = addAct("saveas.png", SLOT(exportAppSettings())); + importAppSettingsAct = addAct("open.png", SLOT(importAppSettings())); + burnConfigAct = addAct("configure.png", SLOT(burnConfig())); - editSplashAct = addAct("paintbrush.png", SLOT(customizeSplash())); - burnListAct = addAct("list.png", SLOT(burnList())); - readFlashAct = addAct("read_flash.png", SLOT(readFlash())); - writeFlashAct = addAct("write_flash.png", SLOT(writeFlash())); - writeSettingsAct = addAct("write_eeprom.png", SLOT(writeSettings())); - readSettingsAct = addAct("read_eeprom.png", SLOT(readSettings())); - burnConfigAct = addAct("configure.png", SLOT(burnConfig())); + compareAct = addAct("compare.png", SLOT(compare()), tr("Ctrl+Alt+R")); + updatesAct = addAct("download.png", SLOT(updates()), tr("Ctrl+Alt+D")); + editSplashAct = addAct("paintbrush.png", SLOT(customizeSplash())); + // assigned menus in createMenus() + profilesMenuAct = addAct("profiles.png"); + createProfileAct = addAct("new.png", SLOT(createProfile())); + copyProfileAct = addAct("copy.png", SLOT(copyProfile())); + deleteProfileAct = addAct("clear.png", SLOT(deleteCurrentProfile())); + sdsyncAct = addAct("sdsync.png", SLOT(sdsync())); + logsAct = addAct("logs.png", SLOT(logFile()), tr("Ctrl+Alt+L")); - writeBUToRadioAct = addAct("write_eeprom_file.png", SLOT(writeBackup())); - readBUToFileAct = addAct("read_eeprom_file.png", SLOT(readBackup())); + burnListAct = addAct("list.png", SLOT(burnList())); + readFlashAct = addAct("read_flash.png", SLOT(readFlash())); + writeFlashAct = addAct("write_flash.png", SLOT(writeFlash())); + writeSettingsAct = addAct("write_eeprom.png", SLOT(writeSettings())); + readSettingsAct = addAct("read_eeprom.png", SLOT(readSettings())); + writeBUToRadioAct = addAct("write_eeprom_file.png", SLOT(writeBackup())); + readBUToFileAct = addAct("read_eeprom_file.png", SLOT(readBackup())); - createProfileAct = addAct("new.png", SLOT(createProfile())); - copyProfileAct = addAct("copy.png", SLOT(copyProfile())); - deleteProfileAct = addAct("clear.png", SLOT(deleteCurrentProfile())); + viewFileToolbarAct = addAct("", SLOT(viewFileToolbar())); + viewModelsToolbarAct = addAct("", SLOT(viewModelsToolbar())); + viewRadioToolbarAct = addAct("", SLOT(viewRadioToolbar())); + viewSettingsToolbarAct = addAct("", SLOT(viewSettingsToolbar())); + viewToolsToolbarAct = addAct("", SLOT(viewToolsToolbar())); - exportSettingsAct = addAct("saveas.png", SLOT(exportSettings())); - importSettingsAct = addAct("open.png", SLOT(importSettings())); + tabbedWindowsAct = addAct("", SLOT(setTabbedWindows(bool)), 0, this, SIGNAL(triggered(bool))); + tileWindowsAct = addAct("", SLOT(tileSubWindows()), 0, mdiArea); + cascadeWindowsAct = addAct("", SLOT(cascadeSubWindows()), 0, mdiArea); + closeAllWindowsAct = addAct("", SLOT(closeAllSubWindows()), 0, mdiArea); - actTabbedWindows = addAct("", SLOT(setTabbedWindows(bool)), 0, this, SIGNAL(triggered(bool))); - actTileWindows = addAct("", SLOT(tileSubWindows()), 0, mdiArea); - actCascadeWindows = addAct("", SLOT(cascadeSubWindows()), 0, mdiArea); - actCloseAllWindows = addAct("", SLOT(closeAllSubWindows()), 0, mdiArea); - - manualChkForUpdAct = addAct("update.png", SLOT(manualCheckForUpdates())); - aboutAct = addAct("information.png", SLOT(about())); - //openDocURLAct = addAct("changelog.png", SLOT(openDocURL())); - changelogAct = addAct("changelog.png", SLOT(changelog())); - - // these two get assigned menus in createMenus() - recentFilesAct = addAct("recentdocument.png"); - profilesMenuAct = addAct("profiles.png"); + manualChkForUpdAct = addAct("update.png", SLOT(manualCheckForUpdates())); + changelogAct = addAct("changelog.png", SLOT(changelog())); + aboutAct = addAct("information.png", SLOT(about())); exitAct->setMenuRole(QAction::QuitRole); aboutAct->setMenuRole(QAction::AboutRole); - appPrefsAct->setMenuRole(QAction::PreferencesRole); - //openDocURLAct->setMenuRole(QAction::ApplicationSpecificRole); - //manualChkForUpdAct->setMenuRole(QAction::ApplicationSpecificRole); + editAppSettingsAct->setMenuRole(QAction::PreferencesRole); changelogAct->setMenuRole(QAction::ApplicationSpecificRole); - actTabbedWindows->setCheckable(true); compareAct->setEnabled(false); + + setActCheckability(tabbedWindowsAct, false); + setActCheckability(viewFileToolbarAct, g.fileToolbarVisible()); + setActCheckability(viewModelsToolbarAct, g.modelsToolbarVisible()); + setActCheckability(viewRadioToolbarAct, g.radioToolbarVisible()); + setActCheckability(viewSettingsToolbarAct, g.settingsToolbarVisible()); + setActCheckability(viewToolsToolbarAct, g.toolsToolbarVisible()); } void MainWindow::createMenus() @@ -929,19 +959,23 @@ void MainWindow::createMenus() fileMenu->addAction(closeAct); fileMenu->addAction(recentFilesAct); fileMenu->addSeparator(); - fileMenu->addAction(logsAct); - fileMenu->addAction(downloadsAct); - fileMenu->addAction(compareAct); - fileMenu->addAction(sdsyncAct); + fileMenu->addAction(readSettingsSDPathAct); + fileMenu->addAction(writeSettingsSDPathAct); fileMenu->addSeparator(); fileMenu->addAction(exitAct); - editMenu = menuBar()->addMenu(""); + viewMenu = menuBar()->addMenu(""); + viewMenu->addAction(viewFileToolbarAct); + viewMenu->addAction(viewModelsToolbarAct); + viewMenu->addAction(viewRadioToolbarAct); + viewMenu->addAction(viewSettingsToolbarAct); + viewMenu->addAction(viewToolsToolbarAct); + viewMenu->addSeparator(); + viewMenu->addMenu(createLanguageMenu(viewMenu)); - settingsMenu = menuBar()->addMenu(""); - settingsMenu->addMenu(createLanguageMenu(settingsMenu)); + modelsMenu = menuBar()->addMenu(""); - themeMenu = settingsMenu->addMenu(""); + themeMenu = viewMenu->addMenu(""); QActionGroup * themeGroup = new QActionGroup(themeMenu); addActToGroup(themeGroup, tr("Classical"), tr("The classic companion9x icon theme"), "themeId", 0, g.theme()); addActToGroup(themeGroup, tr("Yerico"), tr("Yellow round honey sweet icon theme"), "themeId", 1, g.theme()); @@ -951,7 +985,7 @@ void MainWindow::createMenus() connect(themeGroup, &QActionGroup::triggered, this, &MainWindow::onThemeChanged); themeMenu->addActions(themeGroup->actions()); - iconThemeSizeMenu = settingsMenu->addMenu(""); + iconThemeSizeMenu = viewMenu->addMenu(""); QActionGroup * szGroup = new QActionGroup(iconThemeSizeMenu); addActToGroup(szGroup, tr("Small"), tr("Use small toolbar icons"), "sizeId", 0, g.iconSize()); addActToGroup(szGroup, tr("Normal"), tr("Use normal size toolbar icons"), "sizeId", 1, g.iconSize()); @@ -960,41 +994,42 @@ void MainWindow::createMenus() connect(szGroup, &QActionGroup::triggered, this, &MainWindow::onIconSizeChanged); iconThemeSizeMenu->addActions(szGroup->actions()); - settingsMenu->addSeparator(); - settingsMenu->addAction(appPrefsAct); - settingsMenu->addAction(profilesMenuAct); - settingsMenu->addAction(editSplashAct); - settingsMenu->addAction(burnConfigAct); - settingsMenu->addSeparator(); - settingsMenu->addAction(exportSettingsAct); - settingsMenu->addAction(importSettingsAct); + radioMenu = menuBar()->addMenu(""); + radioMenu->addAction(writeSettingsAct); + radioMenu->addAction(readSettingsAct); + radioMenu->addSeparator(); + radioMenu->addAction(writeBUToRadioAct); + radioMenu->addAction(readBUToFileAct); + radioMenu->addSeparator(); + radioMenu->addAction(writeFlashAct); + radioMenu->addAction(readFlashAct); + radioMenu->addSeparator(); + radioMenu->addAction(burnConfigAct); + radioMenu->addAction(editSplashAct); - burnMenu = menuBar()->addMenu(""); - burnMenu->addAction(writeSettingsAct); - burnMenu->addAction(readSettingsAct); - burnMenu->addSeparator(); - burnMenu->addAction(writeBUToRadioAct); - burnMenu->addAction(readBUToFileAct); - burnMenu->addSeparator(); - burnMenu->addAction(writeFlashAct); - burnMenu->addAction(readFlashAct); - burnMenu->addSeparator(); - burnMenu->addSeparator(); + settingsMenu = menuBar()->addMenu(""); + settingsMenu->addAction(editAppSettingsAct); + settingsMenu->addAction(exportAppSettingsAct); + settingsMenu->addAction(importAppSettingsAct); + settingsMenu->addSeparator(); + settingsMenu->addAction(profilesMenuAct); + + toolsMenu = menuBar()->addMenu(""); + toolsMenu->addAction(updatesAct); + toolsMenu->addAction(sdsyncAct); + toolsMenu->addAction(logsAct); + toolsMenu->addSeparator(); windowMenu = menuBar()->addMenu(""); - windowMenu->addAction(actTabbedWindows); - windowMenu->addAction(actTileWindows); - windowMenu->addAction(actCascadeWindows); - windowMenu->addAction(actCloseAllWindows); + windowMenu->addAction(tabbedWindowsAct); + windowMenu->addAction(tileWindowsAct); + windowMenu->addAction(cascadeWindowsAct); + windowMenu->addAction(closeAllWindowsAct); windowMenu->addSeparator(); helpMenu = menuBar()->addMenu(""); helpMenu->addAction(manualChkForUpdAct); - //helpMenu->addSeparator(); - //helpMenu->addAction(openDocURLAct); - //helpMenu->addSeparator(); helpMenu->addAction(changelogAct); - //helpMenu->addSeparator(); helpMenu->addAction(aboutAct); recentFilesMenu = new QMenu(this); @@ -1008,7 +1043,7 @@ void MainWindow::createMenus() profilesMenu = new QMenu(this); QActionGroup *profilesGroup = new QActionGroup(this); - for (int i=0; i < MAX_PROFILES; i++) { + for (int i = 0; i < MAX_PROFILES; i++) { profileActs.append(profilesMenu->addAction("")); profileActs[i]->setVisible(false); profileActs[i]->setCheckable(true); @@ -1032,46 +1067,81 @@ void MainWindow::createToolBars() fileToolBar->addAction(saveAct); fileToolBar->addAction(closeAct); fileToolBar->addSeparator(); - fileToolBar->addAction(logsAct); - fileToolBar->addAction(downloadsAct); - fileToolBar->addSeparator(); - fileToolBar->addAction(appPrefsAct); - fileToolBar->addAction(profilesMenuAct); - fileToolBar->addAction(editSplashAct); - fileToolBar->addAction(editSplashAct); - fileToolBar->addSeparator(); - fileToolBar->addAction(compareAct); - fileToolBar->addAction(sdsyncAct); + fileToolBar->addAction(readSettingsSDPathAct); + fileToolBar->addAction(writeSettingsSDPathAct); // workaround for default split button appearance of action with menu :-/ QToolButton * btn; if ((btn = qobject_cast(fileToolBar->widgetForAction(recentFilesAct)))) btn->setPopupMode(QToolButton::InstantPopup); - if ((btn = qobject_cast(fileToolBar->widgetForAction(profilesMenuAct)))) - btn->setPopupMode(QToolButton::InstantPopup); // gets populated later - editToolBar = addToolBar(""); - editToolBar->setObjectName("Edit"); + modelsToolBar = addToolBar(""); + modelsToolBar->setObjectName("Models"); - burnToolBar = new QToolBar(this); - addToolBar( Qt::LeftToolBarArea, burnToolBar ); - burnToolBar->setObjectName("Write"); - burnToolBar->addAction(writeSettingsAct); - burnToolBar->addAction(readSettingsAct); - burnToolBar->addSeparator(); - burnToolBar->addAction(writeBUToRadioAct); - burnToolBar->addAction(readBUToFileAct); - burnToolBar->addSeparator(); - burnToolBar->addAction(writeFlashAct); - burnToolBar->addAction(readFlashAct); - burnToolBar->addSeparator(); - burnToolBar->addAction(burnConfigAct); + radioToolBar = new QToolBar(this); + addToolBar(Qt::LeftToolBarArea, radioToolBar); + radioToolBar->setObjectName("Radio"); + radioToolBar->addAction(writeSettingsAct); + radioToolBar->addAction(readSettingsAct); + radioToolBar->addSeparator(); + radioToolBar->addAction(writeBUToRadioAct); + radioToolBar->addAction(readBUToFileAct); + radioToolBar->addSeparator(); + radioToolBar->addAction(writeFlashAct); + radioToolBar->addAction(readFlashAct); + radioToolBar->addSeparator(); + radioToolBar->addAction(burnConfigAct); + + settingsToolBar = addToolBar(""); + settingsToolBar->setObjectName("Settings"); + settingsToolBar->addAction(editAppSettingsAct); + settingsToolBar->addAction(profilesMenuAct); + + if ((btn = qobject_cast(settingsToolBar->widgetForAction(profilesMenuAct)))) + btn->setPopupMode(QToolButton::InstantPopup); + + toolsToolBar = addToolBar(""); + toolsToolBar->setObjectName("Tools"); + toolsToolBar->addAction(updatesAct); + toolsToolBar->addAction(sdsyncAct); + toolsToolBar->addAction(logsAct); + + connect(fileToolBar, &QToolBar::visibilityChanged, [=](bool visible) + { + g.fileToolbarVisible(visible); + const QSignalBlocker blocker(viewFileToolbarAct); + viewFileToolbarAct->setChecked(g.fileToolbarVisible()); + }); + + connect(modelsToolBar, &QToolBar::visibilityChanged, [=](bool visible) + { + g.modelsToolbarVisible(visible); + const QSignalBlocker blocker(viewModelsToolbarAct); + viewModelsToolbarAct->setChecked(g.modelsToolbarVisible()); + }); + + connect(radioToolBar, &QToolBar::visibilityChanged, [=](bool visible) + { + g.radioToolbarVisible(visible); + const QSignalBlocker blocker(viewRadioToolbarAct); + viewRadioToolbarAct->setChecked(g.radioToolbarVisible()); + }); + + connect(settingsToolBar, &QToolBar::visibilityChanged, [=](bool visible) + { + g.settingsToolbarVisible(visible); + const QSignalBlocker blocker(viewSettingsToolbarAct); + viewSettingsToolbarAct->setChecked(g.settingsToolbarVisible()); + }); + + connect(toolsToolBar, &QToolBar::visibilityChanged, [=](bool visible) + { + g.toolsToolbarVisible(visible); + const QSignalBlocker blocker(viewToolsToolbarAct); + viewToolsToolbarAct->setChecked(g.toolsToolbarVisible()); + }); - helpToolBar = addToolBar(""); - helpToolBar->setObjectName("Help"); - helpToolBar->addAction(manualChkForUpdAct); - helpToolBar->addAction(aboutAct); } QMenu * MainWindow::createLanguageMenu(QWidget * parent) @@ -1262,7 +1332,7 @@ int MainWindow::newProfile(bool loadProfile) if (loadProfile) { if (loadProfileId(i)) - appPrefs(); + editAppSettings(); } return i; @@ -1281,7 +1351,7 @@ void MainWindow::copyProfile() g.profile[newId] = g.profile[g.id()]; g.profile[newId].name(g.profile[newId].name() + tr(" - Copy")); if (loadProfileId(newId)) - appPrefs(); + editAppSettings(); } } @@ -1316,12 +1386,12 @@ void MainWindow::deleteCurrentProfile() deleteProfile(g.id()); } -void MainWindow::exportSettings() +void MainWindow::exportAppSettings() { Helpers::exportAppSettings(); } -void MainWindow::importSettings() +void MainWindow::importAppSettings() { if (anyChildrenDirty()) { QMessageBox::warning(this, CPN_STR_APP_NAME, tr("Please save or close all modified files before importing settings")); @@ -1416,3 +1486,95 @@ void MainWindow::chooseProfile() g.warningId(g.warningId() | AppMessages::MSG_NO_RADIO_TYPE); } } + +void MainWindow::readSettingsSDPath() +{ + QString tempFile; + tempFile = generateProcessUniqueTempFileName("temp.etx"); + qDebug() << "Reading models and settings from SD path into temp file: " << tempFile; + + if (readSettingsFromSDPath(tempFile)) { + MdiChild * child = createMdiChild(); + child->newFile(false); + child->loadFile(tempFile, false); + child->show(); + qunlink(tempFile); + } +} + +bool MainWindow::readSettingsFromSDPath(const QString & filename) +{ + ProgressDialog progressDialog(this, tr("Read Models and Settings from SD path"), CompanionIcon("read_eeprom.png")); + bool result = ::readSettingsSDCard(filename, progressDialog.progress(), false); + if (!result) { + if (!progressDialog.isEmpty()) { + progressDialog.exec(); + } + } + else { + statusBar()->showMessage(tr("Models and Settings read"), 2000); + } + return result; +} + +void MainWindow::writeSettingsSDPath() +{ + StatusDialog *status = new StatusDialog(this, tr("Writing models and settings to SD path"), tr("In progress..."), 400); + + if (activeMdiChild()) + activeMdiChild()->writeSettings(status, false); + + delete status; +} + +bool MainWindow::isSDPathValid() +{ + bool ret = false; + const QString sdPath = g.currentProfile().sdPath(); + if (!sdPath.isEmpty()) { + if (QFile::exists(sdPath)) + ret = true; + } + return ret; +} + +void MainWindow::setActCheckability(QAction * act, bool checked) +{ + act->setCheckable(true); + act->setChecked(checked); +} + +void MainWindow::viewFileToolbar() +{ + g.fileToolbarVisible(viewFileToolbarAct->isChecked()); + const QSignalBlocker blocker(fileToolBar); + fileToolBar->setVisible(viewFileToolbarAct->isChecked()); +} + +void MainWindow::viewModelsToolbar() +{ + g.modelsToolbarVisible(viewModelsToolbarAct->isChecked()); + const QSignalBlocker blocker(modelsToolBar); + modelsToolBar->setVisible(viewModelsToolbarAct->isChecked()); +} + +void MainWindow::viewRadioToolbar() +{ + g.radioToolbarVisible(viewRadioToolbarAct->isChecked()); + const QSignalBlocker blocker(radioToolBar); + radioToolBar->setVisible(viewRadioToolbarAct->isChecked()); +} + +void MainWindow::viewSettingsToolbar() +{ + g.settingsToolbarVisible(viewSettingsToolbarAct->isChecked()); + const QSignalBlocker blocker(settingsToolBar); + settingsToolBar->setVisible(viewSettingsToolbarAct->isChecked()); +} + +void MainWindow::viewToolsToolbar() +{ + g.toolsToolbarVisible(viewToolsToolbarAct->isChecked()); + const QSignalBlocker blocker(toolsToolBar); + toolsToolBar->setVisible(viewToolsToolbarAct->isChecked()); +} diff --git a/companion/src/mainwindow.h b/companion/src/mainwindow.h index 6014fe759..f90b9ad03 100644 --- a/companion/src/mainwindow.h +++ b/companion/src/mainwindow.h @@ -101,23 +101,32 @@ class MainWindow : public QMainWindow void customizeSplash(); void about(); void compare(); - void appPrefs(); void updateMenus(); void createProfile(); void copyProfile(); void deleteProfile(const int pid); void deleteCurrentProfile(); - void exportSettings(); - void importSettings(); + void editAppSettings(); + void exportAppSettings(); + void importAppSettings(); void autoClose(); void chooseProfile(); void autoCheckForUpdates(); void manualCheckForUpdates(); - void downloads(); + void updates(); void doUpdates(bool check, bool interactive = true); void openFile(const QString & fileName); + void readSettingsSDPath(); + void writeSettingsSDPath(); + + void viewFileToolbar(); + void viewModelsToolbar(); + void viewRadioToolbar(); + void viewSettingsToolbar(); + void viewToolsToolbar(); + private: QAction * addAct(const QString & icon, const char * slot = NULL, const QKeySequence & shortcut = 0, QObject * slotObj = NULL, const char * signal = NULL); QAction * addActToGroup(QActionGroup * aGroup, const QString & sName, const QString & lName, const char * propName = 0, @@ -126,6 +135,8 @@ class MainWindow : public QMainWindow QMenu * createLanguageMenu(QWidget * parent = Q_NULLPTR); + void setActCheckability(QAction * act, bool checked); + void createActions(); void createMenus(); void createToolBars(); @@ -143,9 +154,12 @@ class MainWindow : public QMainWindow bool readSettingsFromRadio(const QString & filename); bool readFirmwareFromRadio(const QString & filename); + bool readSettingsFromSDPath(const QString & filename); bool checkProfileRadioExists(int profId); + bool isSDPathValid(); + QMdiArea *mdiArea; QString installer_fileName; @@ -155,21 +169,30 @@ class MainWindow : public QMainWindow QVector profileActs; QList fileWindowActions; + // top level menus QMenu *fileMenu; - QMenu *editMenu; + QMenu *modelsMenu; + QMenu *viewMenu; QMenu *settingsMenu; - QMenu *burnMenu; - QMenu *helpMenu; + QMenu *radioMenu; + QMenu *toolsMenu; QMenu *windowMenu; + QMenu *helpMenu; + + // sub menus QMenu *iconThemeSizeMenu; QMenu *themeMenu; QMenu *recentFilesMenu; QMenu *profilesMenu; + QActionGroup * windowsListActions; + QToolBar *fileToolBar; - QToolBar *editToolBar; - QToolBar *burnToolBar; - QToolBar *helpToolBar; + QToolBar *modelsToolBar; + QToolBar *radioToolBar; + QToolBar *settingsToolBar; + QToolBar *toolsToolBar; + QAction *newAct; QAction *openAct; QAction *saveAct; @@ -177,8 +200,8 @@ class MainWindow : public QMainWindow QAction *closeAct; QAction *recentFilesAct; QAction *exitAct; - QAction *appPrefsAct; - QAction *downloadsAct; + QAction *editAppSettingsAct; + QAction *updatesAct; QAction *manualChkForUpdAct; QAction *sdsyncAct; QAction *changelogAct; @@ -198,11 +221,17 @@ class MainWindow : public QMainWindow QAction *createProfileAct; QAction *copyProfileAct; QAction *deleteProfileAct; - QAction *exportSettingsAct; - QAction *importSettingsAct; - //QAction *openDocURLAct; - QAction *actTabbedWindows; - QAction *actTileWindows; - QAction *actCascadeWindows; - QAction *actCloseAllWindows; + QAction *exportAppSettingsAct; + QAction *importAppSettingsAct; + QAction *tabbedWindowsAct; + QAction *tileWindowsAct; + QAction *cascadeWindowsAct; + QAction *closeAllWindowsAct; + QAction *writeSettingsSDPathAct; + QAction *readSettingsSDPathAct; + QAction *viewFileToolbarAct; + QAction *viewModelsToolbarAct; + QAction *viewRadioToolbarAct; + QAction *viewSettingsToolbarAct; + QAction *viewToolsToolbarAct; }; diff --git a/companion/src/mdichild.cpp b/companion/src/mdichild.cpp index 2fe03a3d1..ab13be5d3 100644 --- a/companion/src/mdichild.cpp +++ b/companion/src/mdichild.cpp @@ -216,19 +216,12 @@ void MdiChild::setupNavigation() addAct(ACT_GEN_PST, "paste.png", SLOT(pasteGeneralSettings()), tr("Ctrl+Alt+V")); addAct(ACT_GEN_SIM, "simulate.png", SLOT(radioSimulate()), tr("Alt+Shift+S")); - addAct(ACT_ITM_EDT, "edit.png", SLOT(edit()), Qt::Key_Enter); - addAct(ACT_ITM_DEL, "clear.png", SLOT(confirmDelete()), QKeySequence::Delete); - + addAct(ACT_MDL_EDT, "edit.png", SLOT(edit()), Qt::Key_Enter); + addAct(ACT_MDL_DEL, "clear.png", SLOT(confirmDelete()), QKeySequence::Delete); addAct(ACT_MDL_ADD, "add.png", SLOT(modelAdd()), tr("Alt+A")); addAct(ACT_MDL_RTR, "open.png", SLOT(loadBackup()), tr("Alt+R")); addAct(ACT_MDL_WIZ, "wizard.png", SLOT(wizardEdit()), tr("Alt+W")); - addAct(ACT_LBL_ADD, "add.png", SLOT(labelAdd()), tr("Alt-L")); - addAct(ACT_LBL_DEL, "clear.png", SLOT(labelDelete()), tr("Alt-L")); - addAct(ACT_LBL_REN, "edit.png", SLOT(labelRename()), tr("Alt-R")); - addAct(ACT_LBL_MVU, "moveup.png", SLOT(labelMoveUp()), tr("Alt-+")); - addAct(ACT_LBL_MVD, "movedown.png", SLOT(labelMoveDown()), tr("Alt--")); - addAct(ACT_MDL_DFT, "currentmodel.png", SLOT(setDefault()), tr("Alt+U")); addAct(ACT_MDL_PRT, "print.png", SLOT(print()), QKeySequence::Print); addAct(ACT_MDL_SIM, "simulate.png", SLOT(modelSimulate()), tr("Alt+S")); @@ -244,6 +237,12 @@ void MdiChild::setupNavigation() QMenu * catsMenu = new QMenu(this); action[ACT_MDL_MOV]->setMenu(catsMenu); + addAct(ACT_LBL_ADD, "add.png", SLOT(labelAdd()), tr("Alt-L")); + addAct(ACT_LBL_DEL, "clear.png", SLOT(labelDelete()), tr("Alt-L")); + addAct(ACT_LBL_REN, "edit.png", SLOT(labelRename()), tr("Alt-R")); + addAct(ACT_LBL_MVU, "moveup.png", SLOT(labelMoveUp()), tr("Alt-+")); + addAct(ACT_LBL_MVD, "movedown.png", SLOT(labelMoveDown()), tr("Alt--")); + // set up the toolbars QToolButton * btn; @@ -352,6 +351,8 @@ void MdiChild::updateNavigation() } action[ACT_GEN_SRT]->setVisible(hasLabels); + action[ACT_MDL_DEL]->setEnabled(modelsSelected); + action[ACT_MDL_DEL]->setText(tr("Delete") % (modelsSelected ? sp % modelsRemvTxt : ns)); action[ACT_MDL_CUT]->setEnabled(modelsSelected); action[ACT_MDL_CUT]->setText(tr("Cut") % (modelsSelected ? sp % modelsRemvTxt : ns)); action[ACT_MDL_CPY]->setEnabled(modelsSelected); @@ -379,8 +380,8 @@ void MdiChild::retranslateUi() action[ACT_GEN_SIM]->setText(tr("Simulate Radio")); cboModelSortOrder->setToolTip(tr("Radio Models Order")); - action[ACT_ITM_EDT]->setText(tr("Edit Model")); - action[ACT_ITM_DEL]->setText(tr("Delete")); + action[ACT_MDL_EDT]->setText(tr("Edit Model")); + action[ACT_MDL_DEL]->setText(tr("Delete Model")); action[ACT_LBL_ADD]->setText(tr("Add")); action[ACT_LBL_DEL]->setText(tr("Delete")); @@ -408,6 +409,7 @@ QList MdiChild::getGeneralActions() { QList actGrp; actGrp.append(getAction(ACT_GEN_SIM)); + actGrp.append(actionsSeparator()); actGrp.append(getAction(ACT_GEN_EDT)); actGrp.append(getAction(ACT_GEN_CPY)); actGrp.append(getAction(ACT_GEN_PST)); @@ -418,27 +420,28 @@ QList MdiChild::getEditActions() { QList actGrp; actGrp.append(action[ACT_MDL_ADD]); - QAction * sep2 = new QAction(this); - sep2->setSeparator(true); - actGrp.append(sep2); - actGrp.append(getAction(ACT_ITM_EDT)); - actGrp.append(getAction(ACT_ITM_DEL)); + actGrp.append(actionsSeparator()); + actGrp.append(getAction(ACT_MDL_EDT)); + actGrp.append(getAction(ACT_MDL_DEL)); actGrp.append(getAction(ACT_MDL_CUT)); actGrp.append(getAction(ACT_MDL_CPY)); actGrp.append(getAction(ACT_MDL_PST)); actGrp.append(getAction(ACT_MDL_INS)); actGrp.append(getAction(ACT_MDL_DUP)); - actGrp.append(getAction(ACT_MDL_MOV)); actGrp.append(getAction(ACT_MDL_EXP)); + actGrp.append(getAction(ACT_MDL_MOV)); return actGrp; } QList MdiChild::getModelActions() { QList actGrp; - actGrp.append(getAction(ACT_MDL_RTR)); actGrp.append(getAction(ACT_MDL_WIZ)); actGrp.append(getAction(ACT_MDL_DFT)); + // TODO remove + // the function has been hobbled as expects eeprom binary backup so do not list + // can just open another etx so use case doubtful + //actGrp.append(getAction(ACT_MDL_RTR)); actGrp.append(getAction(ACT_MDL_PRT)); actGrp.append(getAction(ACT_MDL_SIM)); return actGrp; @@ -1481,12 +1484,12 @@ int MdiChild::askQuestion(const QString & msg, QMessageBox::StandardButtons butt return QMessageBox::question(this, CPN_STR_APP_NAME, msg, buttons, defaultButton); } -void MdiChild::writeSettings(StatusDialog * status) // write to Tx +void MdiChild::writeSettings(StatusDialog * status, bool toRadio) // write to Tx { if (g.confirmWriteModelsAndSettings()) { QMessageBox msgbox; - msgbox.setText(tr("You are about to overwrite ALL models on the Radio.")); - msgbox.setInformativeText(tr("Do you want to continue?")); + msgbox.setText(tr("You are about to overwrite ALL models.")); + msgbox.setInformativeText(tr("Continue?")); msgbox.setIcon(QMessageBox::Icon::Question); msgbox.setStandardButtons(QMessageBox::Yes | QMessageBox::Abort); msgbox.setDefaultButton(QMessageBox::Abort); @@ -1499,21 +1502,31 @@ void MdiChild::writeSettings(StatusDialog * status) // write to Tx return; } - QString radioPath = findMassstoragePath("RADIO", true); - qDebug() << "Searching for SD card, found" << radioPath; + QString radioPath; + + if (toRadio) { + radioPath = findMassstoragePath("RADIO", true); + qDebug() << "Searching for SD card, found" << radioPath; + } + else { + radioPath = g.currentProfile().sdPath(); + if (!QFile(radioPath % "/RADIO").exists()) + radioPath.clear(); + } + if (radioPath.isEmpty()) { qDebug() << "Radio SD card not found"; - QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Unable to find radio SD card!")); + QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Unable to find SD card!")); return; } if (saveFile(radioPath, false)) { status->hide(); - QMessageBox::information(this, CPN_STR_TTL_INFO, tr("Models and settings written to radio")); + QMessageBox::information(this, CPN_STR_TTL_INFO, tr("Models and settings written")); } else { status->hide(); - QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Error writing models and settings to radio!")); + QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Error writing models and settings!")); } } @@ -1834,3 +1847,10 @@ void MdiChild::setModelModified(const int modelIndex, bool cascade) setModified(); } } + +QAction * MdiChild::actionsSeparator() +{ + QAction * act = new QAction(this); + act->setSeparator(true); + return act; +} diff --git a/companion/src/mdichild.h b/companion/src/mdichild.h index fa3fbcd69..49f4cbc34 100644 --- a/companion/src/mdichild.h +++ b/companion/src/mdichild.h @@ -55,14 +55,9 @@ class MdiChild : public QWidget ACT_GEN_PST, ACT_GEN_SIM, ACT_GEN_SRT, // model sort order - ACT_ITM_EDT, - ACT_ITM_DEL, - ACT_LBL_ADD, - ACT_LBL_DEL, - ACT_LBL_MVU, // Move up - ACT_LBL_MVD, // Move down - ACT_LBL_REN, // Move down - ACT_MDL_ADD, // model actions... + ACT_MDL_EDT, // model actions... + ACT_MDL_DEL, + ACT_MDL_ADD, ACT_MDL_CPY, ACT_MDL_CUT, ACT_MDL_PST, @@ -75,6 +70,11 @@ class MdiChild : public QWidget ACT_MDL_DFT, // set as DeFaulT ACT_MDL_PRT, // print ACT_MDL_SIM, + ACT_LBL_ADD, // label actions.. + ACT_LBL_DEL, + ACT_LBL_MVU, // Move up + ACT_LBL_MVD, // Move down + ACT_LBL_REN, // Move down ACT_ENUM_END }; @@ -97,7 +97,7 @@ class MdiChild : public QWidget bool saveAs(bool isNew=false); bool saveFile(const QString & fileName, bool setCurrent=true); void closeFile(bool force = false); - void writeSettings(StatusDialog * status); + void writeSettings(StatusDialog * status, bool toRadio = true); void print(int model=-1, const QString & filename=""); void onFirmwareChanged(); @@ -231,6 +231,7 @@ class MdiChild : public QWidget AbstractStaticItemModel* modelSortOrderItemModel; QComboBox* cboModelSortOrder; void setModelModified(const int modelIndex, bool cascade = true); + QAction * actionsSeparator(); }; // This will draw the drop indicator across all columns of a model View (vs. in just one column), and lets us make the indicator more obvious. diff --git a/companion/src/radiointerface.cpp b/companion/src/radiointerface.cpp index 37265cf62..afe08f836 100644 --- a/companion/src/radiointerface.cpp +++ b/companion/src/radiointerface.cpp @@ -189,21 +189,25 @@ bool readSettings(const QString & filename, ProgressWidget * progress) return readSettingsEeprom(filename, progress); } -bool readSettingsSDCard(const QString & filename, ProgressWidget * progress) +bool readSettingsSDCard(const QString & filename, ProgressWidget * progress, bool fromRadio) { - QString radioPath = findMassstoragePath("RADIO", true, progress); - qDebug() << "Searching for SD card, found" << radioPath; - if (radioPath.isEmpty()) { - QMessageBox::critical(progress, CPN_STR_TTL_ERROR, - QCoreApplication::translate("RadioInterface", "Unable to find radio SD card!")); - return false; + QString radioPath; + + if (fromRadio) { + radioPath = findMassstoragePath("RADIO", true, progress); + qDebug() << "Searching for SD card, found" << radioPath; + } + else { + radioPath = g.currentProfile().sdPath(); + if (!QFile::exists(radioPath % "/RADIO")) + radioPath.clear(); } - // if radio.yml it is a converted radio - // if radio.bin unconverted pre 2.6 - // if neither then unconverted eeprom or empty - if (!QFile::exists(radioPath % "/RADIO/radio.yml") && !QFile::exists(radioPath % "/RADIO/radio.bin")) - return readSettingsEeprom(filename, progress); + if (radioPath.isEmpty()) { + QMessageBox::critical(progress, CPN_STR_TTL_ERROR, + QCoreApplication::translate("RadioInterface", "Unable to find SD card!")); + return false; + } RadioData radioData; Storage inputStorage(radioPath); diff --git a/companion/src/radiointerface.h b/companion/src/radiointerface.h index d97bcd983..4b930df9c 100644 --- a/companion/src/radiointerface.h +++ b/companion/src/radiointerface.h @@ -19,8 +19,7 @@ * GNU General Public License for more details. */ -#ifndef _RADIOINTERFACE_H_ -#define _RADIOINTERFACE_H_ +#pragma once #include #include @@ -42,8 +41,6 @@ QStringList getWriteFirmwareArgs(const QString &filename); bool readFirmware(const QString &filename, ProgressWidget *progress); bool writeFirmware(const QString &filename, ProgressWidget *progress); bool readSettings(const QString &filename, ProgressWidget *progress); -bool readSettingsSDCard(const QString &filename, ProgressWidget *progress); +bool readSettingsSDCard(const QString &filename, ProgressWidget *progress, bool fromRadio = true); bool readSettingsEeprom(const QString &filename, ProgressWidget *progress); bool writeSettings(const QString &filename, ProgressWidget *progress); - -#endif // _RADIOINTERFACE_H_ diff --git a/companion/src/storage/appdata.h b/companion/src/storage/appdata.h index 1b57c77f0..119dd8169 100644 --- a/companion/src/storage/appdata.h +++ b/companion/src/storage/appdata.h @@ -835,6 +835,13 @@ class AppData: public CompStoreObj // Message box confirmations PROPERTY(bool, confirmWriteModelsAndSettings, true) + // Toolbars visibility + PROPERTY(bool, fileToolbarVisible, true) + PROPERTY(bool, modelsToolbarVisible, true) + PROPERTY(bool, radioToolbarVisible, true) + PROPERTY(bool, settingsToolbarVisible, true) + PROPERTY(bool, toolsToolbarVisible, true) + bool firstUse; QString upgradeFromVersion; diff --git a/companion/src/themes/classic/16/folder-tree-read.png b/companion/src/themes/classic/16/folder-tree-read.png new file mode 100644 index 000000000..c6c4cecdc Binary files /dev/null and b/companion/src/themes/classic/16/folder-tree-read.png differ diff --git a/companion/src/themes/classic/16/folder-tree-write.png b/companion/src/themes/classic/16/folder-tree-write.png new file mode 100644 index 000000000..d6db5ed08 Binary files /dev/null and b/companion/src/themes/classic/16/folder-tree-write.png differ diff --git a/companion/src/themes/classic/24/folder-tree-read.png b/companion/src/themes/classic/24/folder-tree-read.png new file mode 100644 index 000000000..307a0c3c0 Binary files /dev/null and b/companion/src/themes/classic/24/folder-tree-read.png differ diff --git a/companion/src/themes/classic/24/folder-tree-write.png b/companion/src/themes/classic/24/folder-tree-write.png new file mode 100644 index 000000000..0b61387dc Binary files /dev/null and b/companion/src/themes/classic/24/folder-tree-write.png differ diff --git a/companion/src/themes/classic/32/folder-tree-read.png b/companion/src/themes/classic/32/folder-tree-read.png new file mode 100644 index 000000000..b97aaaf83 Binary files /dev/null and b/companion/src/themes/classic/32/folder-tree-read.png differ diff --git a/companion/src/themes/classic/32/folder-tree-write.png b/companion/src/themes/classic/32/folder-tree-write.png new file mode 100644 index 000000000..85810d684 Binary files /dev/null and b/companion/src/themes/classic/32/folder-tree-write.png differ diff --git a/companion/src/themes/classic/48/folder-tree-read.png b/companion/src/themes/classic/48/folder-tree-read.png new file mode 100644 index 000000000..3e7cbcddd Binary files /dev/null and b/companion/src/themes/classic/48/folder-tree-read.png differ diff --git a/companion/src/themes/classic/48/folder-tree-write.png b/companion/src/themes/classic/48/folder-tree-write.png new file mode 100644 index 000000000..4d12ea148 Binary files /dev/null and b/companion/src/themes/classic/48/folder-tree-write.png differ diff --git a/companion/src/themes/monoblue/16/folder-tree-read.png b/companion/src/themes/monoblue/16/folder-tree-read.png new file mode 100644 index 000000000..fd4a1b479 Binary files /dev/null and b/companion/src/themes/monoblue/16/folder-tree-read.png differ diff --git a/companion/src/themes/monoblue/16/folder-tree-write.png b/companion/src/themes/monoblue/16/folder-tree-write.png new file mode 100644 index 000000000..0fa6d2f48 Binary files /dev/null and b/companion/src/themes/monoblue/16/folder-tree-write.png differ diff --git a/companion/src/themes/monoblue/24/folder-tree-read.png b/companion/src/themes/monoblue/24/folder-tree-read.png new file mode 100644 index 000000000..5852ebb38 Binary files /dev/null and b/companion/src/themes/monoblue/24/folder-tree-read.png differ diff --git a/companion/src/themes/monoblue/24/folder-tree-write.png b/companion/src/themes/monoblue/24/folder-tree-write.png new file mode 100644 index 000000000..711cdb589 Binary files /dev/null and b/companion/src/themes/monoblue/24/folder-tree-write.png differ diff --git a/companion/src/themes/monoblue/32/folder-tree-read.png b/companion/src/themes/monoblue/32/folder-tree-read.png new file mode 100644 index 000000000..3cc3b30c9 Binary files /dev/null and b/companion/src/themes/monoblue/32/folder-tree-read.png differ diff --git a/companion/src/themes/monoblue/32/folder-tree-write.png b/companion/src/themes/monoblue/32/folder-tree-write.png new file mode 100644 index 000000000..063a1860d Binary files /dev/null and b/companion/src/themes/monoblue/32/folder-tree-write.png differ diff --git a/companion/src/themes/monoblue/48/folder-tree-read.png b/companion/src/themes/monoblue/48/folder-tree-read.png new file mode 100644 index 000000000..ffa75386d Binary files /dev/null and b/companion/src/themes/monoblue/48/folder-tree-read.png differ diff --git a/companion/src/themes/monoblue/48/folder-tree-write.png b/companion/src/themes/monoblue/48/folder-tree-write.png new file mode 100644 index 000000000..8c9cf395e Binary files /dev/null and b/companion/src/themes/monoblue/48/folder-tree-write.png differ diff --git a/companion/src/themes/monochrome/16/folder-tree-read.png b/companion/src/themes/monochrome/16/folder-tree-read.png new file mode 100644 index 000000000..db62ca731 Binary files /dev/null and b/companion/src/themes/monochrome/16/folder-tree-read.png differ diff --git a/companion/src/themes/monochrome/16/folder-tree-write.png b/companion/src/themes/monochrome/16/folder-tree-write.png new file mode 100644 index 000000000..92604f36f Binary files /dev/null and b/companion/src/themes/monochrome/16/folder-tree-write.png differ diff --git a/companion/src/themes/monochrome/24/folder-tree-read.png b/companion/src/themes/monochrome/24/folder-tree-read.png new file mode 100644 index 000000000..04d42a07d Binary files /dev/null and b/companion/src/themes/monochrome/24/folder-tree-read.png differ diff --git a/companion/src/themes/monochrome/24/folder-tree-write.png b/companion/src/themes/monochrome/24/folder-tree-write.png new file mode 100644 index 000000000..b19006030 Binary files /dev/null and b/companion/src/themes/monochrome/24/folder-tree-write.png differ diff --git a/companion/src/themes/monochrome/32/folder-tree-read.png b/companion/src/themes/monochrome/32/folder-tree-read.png new file mode 100644 index 000000000..496754b5c Binary files /dev/null and b/companion/src/themes/monochrome/32/folder-tree-read.png differ diff --git a/companion/src/themes/monochrome/32/folder-tree-write.png b/companion/src/themes/monochrome/32/folder-tree-write.png new file mode 100644 index 000000000..4d0ec8323 Binary files /dev/null and b/companion/src/themes/monochrome/32/folder-tree-write.png differ diff --git a/companion/src/themes/monochrome/48/folder-tree-read.png b/companion/src/themes/monochrome/48/folder-tree-read.png new file mode 100644 index 000000000..6f1a5e6b0 Binary files /dev/null and b/companion/src/themes/monochrome/48/folder-tree-read.png differ diff --git a/companion/src/themes/monochrome/48/folder-tree-write.png b/companion/src/themes/monochrome/48/folder-tree-write.png new file mode 100644 index 000000000..c6b5fb0ef Binary files /dev/null and b/companion/src/themes/monochrome/48/folder-tree-write.png differ diff --git a/companion/src/themes/monowhite/16/folder-tree-read.png b/companion/src/themes/monowhite/16/folder-tree-read.png new file mode 100644 index 000000000..bb46e259f Binary files /dev/null and b/companion/src/themes/monowhite/16/folder-tree-read.png differ diff --git a/companion/src/themes/monowhite/16/folder-tree-write.png b/companion/src/themes/monowhite/16/folder-tree-write.png new file mode 100644 index 000000000..89be2c1b5 Binary files /dev/null and b/companion/src/themes/monowhite/16/folder-tree-write.png differ diff --git a/companion/src/themes/monowhite/24/folder-tree-read.png b/companion/src/themes/monowhite/24/folder-tree-read.png new file mode 100644 index 000000000..3e7a66cf8 Binary files /dev/null and b/companion/src/themes/monowhite/24/folder-tree-read.png differ diff --git a/companion/src/themes/monowhite/24/folder-tree-write.png b/companion/src/themes/monowhite/24/folder-tree-write.png new file mode 100644 index 000000000..a14749b39 Binary files /dev/null and b/companion/src/themes/monowhite/24/folder-tree-write.png differ diff --git a/companion/src/themes/monowhite/32/folder-tree-read.png b/companion/src/themes/monowhite/32/folder-tree-read.png new file mode 100644 index 000000000..8057b7a51 Binary files /dev/null and b/companion/src/themes/monowhite/32/folder-tree-read.png differ diff --git a/companion/src/themes/monowhite/32/folder-tree-write.png b/companion/src/themes/monowhite/32/folder-tree-write.png new file mode 100644 index 000000000..76cea1acb Binary files /dev/null and b/companion/src/themes/monowhite/32/folder-tree-write.png differ diff --git a/companion/src/themes/monowhite/48/folder-tree-read.png b/companion/src/themes/monowhite/48/folder-tree-read.png new file mode 100644 index 000000000..f87930d4f Binary files /dev/null and b/companion/src/themes/monowhite/48/folder-tree-read.png differ diff --git a/companion/src/themes/monowhite/48/folder-tree-write.png b/companion/src/themes/monowhite/48/folder-tree-write.png new file mode 100644 index 000000000..86c96905f Binary files /dev/null and b/companion/src/themes/monowhite/48/folder-tree-write.png differ diff --git a/companion/src/themes/yerico/16/folder-tree-read.png b/companion/src/themes/yerico/16/folder-tree-read.png new file mode 100644 index 000000000..5d5e602ea Binary files /dev/null and b/companion/src/themes/yerico/16/folder-tree-read.png differ diff --git a/companion/src/themes/yerico/16/folder-tree-write.png b/companion/src/themes/yerico/16/folder-tree-write.png new file mode 100644 index 000000000..0a43ead45 Binary files /dev/null and b/companion/src/themes/yerico/16/folder-tree-write.png differ diff --git a/companion/src/themes/yerico/24/folder-tree-read.png b/companion/src/themes/yerico/24/folder-tree-read.png new file mode 100644 index 000000000..2d63c31bf Binary files /dev/null and b/companion/src/themes/yerico/24/folder-tree-read.png differ diff --git a/companion/src/themes/yerico/24/folder-tree-write.png b/companion/src/themes/yerico/24/folder-tree-write.png new file mode 100644 index 000000000..dffadcb99 Binary files /dev/null and b/companion/src/themes/yerico/24/folder-tree-write.png differ diff --git a/companion/src/themes/yerico/32/folder-tree-read.png b/companion/src/themes/yerico/32/folder-tree-read.png new file mode 100644 index 000000000..05db22c0f Binary files /dev/null and b/companion/src/themes/yerico/32/folder-tree-read.png differ diff --git a/companion/src/themes/yerico/32/folder-tree-write.png b/companion/src/themes/yerico/32/folder-tree-write.png new file mode 100644 index 000000000..f24ee92ad Binary files /dev/null and b/companion/src/themes/yerico/32/folder-tree-write.png differ diff --git a/companion/src/themes/yerico/48/folder-tree-read.png b/companion/src/themes/yerico/48/folder-tree-read.png new file mode 100644 index 000000000..92e850066 Binary files /dev/null and b/companion/src/themes/yerico/48/folder-tree-read.png differ diff --git a/companion/src/themes/yerico/48/folder-tree-write.png b/companion/src/themes/yerico/48/folder-tree-write.png new file mode 100644 index 000000000..096cbe2d5 Binary files /dev/null and b/companion/src/themes/yerico/48/folder-tree-write.png differ