From 4f9c21f83f14dda3478bf952b90f453f38f6f5ab Mon Sep 17 00:00:00 2001 From: mgrojo Date: Tue, 25 Dec 2018 21:12:11 +0100 Subject: [PATCH] Closable main tabs and saving automatically open tabs and order Main tabs are made closable, so they can be closed by the user. New entries are added to the View menu for toggling their open/closed state. Spartan users can closed all tabs but their preferred, and then the tab bar is hidden saving some space. The set of open tabs and their order is automatically saved in the settings on application exit and restored on application start. Tab labels are stored in the statusTip attribute in order to restore them, since those labels are not stored anywhere else. See issues #1675 and #459 --- src/MainWindow.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++++ src/MainWindow.h | 2 ++ src/MainWindow.ui | 23 ++++++++++++++++++-- src/Settings.cpp | 4 ++++ src/icons/icons.qrc | 1 + src/icons/tab.png | Bin 0 -> 323 bytes 6 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 src/icons/tab.png diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 37e875ad..d291e2e0 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -222,6 +222,19 @@ void MainWindow::init() restoreGeometry(Settings::getValue("MainWindow", "geometry").toByteArray()); restoreState(Settings::getValue("MainWindow", "windowState").toByteArray()); + // Restore open tab order if the openTabs setting is saved. + // Clear the tabs and then add them in the order specified by the setting. + // Use the statusTip attribute for restoring the tab label. + if (!Settings::getValue("MainWindow", "openTabs").toString().isEmpty()) { + ui->mainTab->clear(); + for (QString objectName : Settings::getValue("MainWindow", "openTabs").toString().split(' ')) { + for (QWidget* widget : {ui->structure, ui->browser, ui->pragmas, ui->query}) + if (widget->objectName() == objectName) { + ui->mainTab->addTab(widget, widget->statusTip()); + break; + } + } + } // Restore dock state settings ui->comboLogSubmittedBy->setCurrentIndex(ui->comboLogSubmittedBy->findText(Settings::getValue("SQLLogDock", "Log").toString())); @@ -335,6 +348,25 @@ void MainWindow::init() // Add separator between docks and toolbars ui->viewMenu->insertSeparator(ui->viewDBToolbarAction); + // Connect the tabCloseRequested to the actual closeTab function. + // This must be done before the connections for checking the actions in the View menu so + // they are updated accordingly. + connect(ui->mainTab, &QTabWidget::tabCloseRequested, this, &MainWindow::closeTab); + + // Add entries for toggling the visibility of main tabs + for (QWidget* widget : {ui->structure, ui->browser, ui->pragmas, ui->query}) { + QAction* action = ui->viewMenu->addAction(QIcon(":/icons/tab"), widget->statusTip()); + action->setCheckable(true); + action->setChecked(ui->mainTab->indexOf(widget) != -1); + connect(action, &QAction::toggled, [=](bool show) { toggleTabVisible(widget, show); }); + // Connect tabCloseRequested for setting checked the appropiate menu entry. + // Note these are called after the actual tab is closed only because they are connected + // after connecting closeTab. + connect(ui->mainTab, &QTabWidget::tabCloseRequested, [=](int index) { + action->setChecked(ui->mainTab->indexOf(widget) != -1); + }); + } + // If we're not compiling in SQLCipher, hide its FAQ link in the help menu #ifndef ENABLE_SQLCIPHER ui->actionSqlCipherFaq->setVisible(false); @@ -896,6 +928,12 @@ void MainWindow::closeEvent( QCloseEvent* event ) { Settings::setValue("MainWindow", "geometry", saveGeometry()); Settings::setValue("MainWindow", "windowState", saveState()); + + QString openTabs; + for (int i=0; i < ui->mainTab->count(); i++) + openTabs.append(ui->mainTab->widget(i)->objectName() + ' '); + Settings::setValue("MainWindow", "openTabs", openTabs); + Settings::setValue("SQLLogDock", "Log", ui->comboLogSubmittedBy->currentText()); Settings::setValue("SchemaDock", "dropQualifiedNames", ui->actionDropQualifiedCheck->isChecked()); Settings::setValue("SchemaDock", "dropEnquotedNames", ui->actionEnquoteNamesCheck->isChecked()); @@ -3694,3 +3732,17 @@ void MainWindow::updateDatabaseBusyStatus(bool busy, const QString& user) statusBusyLabel->setVisible(busy); statusStopButton->setVisible(busy); } + + +void MainWindow::closeTab(int index) +{ + ui->mainTab->removeTab(index); +} + +void MainWindow::toggleTabVisible(QWidget* tabWidget, bool show) +{ + if (show) + ui->mainTab->addTab(tabWidget, tabWidget->statusTip()); + else + ui->mainTab->removeTab(ui->mainTab->indexOf(tabWidget)); +} diff --git a/src/MainWindow.h b/src/MainWindow.h index 6ee24495..ed14b837 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -187,6 +187,7 @@ private: sqlb::ObjectIdentifier currentlyBrowsedTableName() const; void applyBrowseTableSettings(BrowseDataTableSettings storedData, bool skipFilters = false); + void toggleTabVisible(QWidget* tabWidget, bool show); protected: void closeEvent(QCloseEvent *) override; @@ -298,6 +299,7 @@ private slots: void printDbStructure(); void updateDatabaseBusyStatus(bool busy, const QString& user); void openPreferences(); + void closeTab(int index); }; #endif diff --git a/src/MainWindow.ui b/src/MainWindow.ui index 19a04311..be5dc129 100644 --- a/src/MainWindow.ui +++ b/src/MainWindow.ui @@ -24,10 +24,19 @@ 0 + + true + true + + true + + + Database Structure + Database Structure @@ -93,6 +102,9 @@ You can drag SQL statements from an object row and drop them into other applicat + + Browse Data + Browse Data @@ -431,6 +443,9 @@ You can drag SQL statements from an object row and drop them into other applicat + + Edit Pragmas + Edit Pragmas @@ -445,8 +460,8 @@ You can drag SQL statements from an object row and drop them into other applicat 0 0 - 601 - 484 + 572 + 510 @@ -946,6 +961,9 @@ You can drag SQL statements from an object row and drop them into other applicat + + Execute SQL + Execute SQL @@ -1056,6 +1074,7 @@ You can drag SQL statements from an object row and drop them into other applicat + diff --git a/src/Settings.cpp b/src/Settings.cpp index 1679cb9c..55998a12 100644 --- a/src/Settings.cpp +++ b/src/Settings.cpp @@ -138,6 +138,10 @@ QVariant Settings::getDefaultValue(const QString& group, const QString& name) if(group == "MainWindow" && name == "windowState") return ""; + // MainWindow/openTabs? + if(group == "MainWindow" && name == "openTabs") + return ""; + // SQLLogDock/Log? if(group == "SQLLogDock" && name == "Log") return "Application"; diff --git a/src/icons/icons.qrc b/src/icons/icons.qrc index e024aba6..a7a82090 100644 --- a/src/icons/icons.qrc +++ b/src/icons/icons.qrc @@ -71,5 +71,6 @@ cancel.png comment_block.png hourglass.png + tab.png diff --git a/src/icons/tab.png b/src/icons/tab.png new file mode 100644 index 0000000000000000000000000000000000000000..3d8207fd74e73ed0a61793834ecbd358a209b9c9 GIT binary patch literal 323 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmUzPnffIy#(?lOI#yL zg7ec#$`gxH85~pclTsBta}(23gHjVyDhp4h+5i<@^>lFzu{fRl=l_3uX4QtyMkj+0 zY#SOnetv##&Ac*9!Aw2qzO90ukB`rtBTS+*)~sK@Qd3Wl>6w91lc$EXqw|d(p7rtj zL#=9mJql4^&ui$IAYgxZvAe!x-T!~wAEkwbV}v;l|IpFV;kk6_P=alNz5|0Yv$3)9 z;rsjlKkS;w>nL%6C&hSi8{-+bv^22=Ol%^&FHDS$JJJrBFsN`$`tyH2>+-h(-T}M` zbIkMa)w8ljvf0|^Ry