Printing support #1525: print DB structure

New action and button for printing the database structure.

The data in the Database Structure tree widget is converted to HTML and set
in a document that can then be printed, opening the dialog as done for
other components.
This commit is contained in:
mgr
2018-09-25 23:00:17 +02:00
parent 97f9a18310
commit 4f0d3505ed
3 changed files with 130 additions and 0 deletions

View File

@@ -52,6 +52,8 @@
#include <QTextCodec>
#include <QUrlQuery>
#include <QDataStream> // This include seems to only be necessary for the Windows build
#include <QPrinter>
#include <QPrintDialog>
#ifdef Q_OS_MACX //Needed only on macOS
#include <QOpenGLWidget>
@@ -180,6 +182,10 @@ void MainWindow::init()
QShortcut* shortcutBrowseRefreshCtrlR = new QShortcut(QKeySequence("Ctrl+R"), this);
connect(shortcutBrowseRefreshCtrlR, SIGNAL(activated()), this, SLOT(refresh()));
// Add print shortcut for the DB Structure tab (dbTreeWidget) with context to the widget, so other print shortcuts aren't eclipsed.
QShortcut* shortcutPrint = new QShortcut(QKeySequence(QKeySequence::Print), ui->dbTreeWidget, nullptr, nullptr, Qt::WidgetShortcut);
connect(shortcutPrint, &QShortcut::activated, this, &MainWindow::printDbStructure);
// Create the actions for the recently opened dbs list
for(int i = 0; i < MaxRecentFiles; ++i) {
recentFileActs[i] = new QAction(this);
@@ -1859,6 +1865,7 @@ void MainWindow::activateFields(bool enable)
ui->fileImportCSVAction->setEnabled(enable && write);
ui->editCreateTableAction->setEnabled(enable && write);
ui->editCreateIndexAction->setEnabled(enable && write);
ui->actionDbPrint->setEnabled(enable);
ui->buttonNext->setEnabled(enable);
ui->buttonPrevious->setEnabled(enable);
ui->buttonBegin->setEnabled(enable);
@@ -3407,3 +3414,81 @@ void MainWindow::runSqlNewTab(const QString& query, const QString& title)
return;
}
}
void MainWindow::printDbStructure ()
{
const QTreeView* treeView = ui->dbTreeWidget;
const QAbstractItemModel* model = treeView->model();
const int rowCount = model->rowCount(treeView->rootIndex());
const int columnCount = model->columnCount(treeView->rootIndex());
QString strStream;
QTextStream out(&strStream);
out << "<html><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">"
<< QString("<title>%1</title>").arg(treeView->windowTitle())
<< "</head><body bgcolor=\"#FFFFFF\">";
for (int row = 0; row < rowCount; row++) {
QModelIndex headerIndex = model->index(row, 0, treeView->rootIndex());
QString data = model->data(headerIndex).toString().toHtmlEscaped();
out << QString("<h1>%1</h1>").arg(data);
// Open a new table for each group of objects
out << "<table border=1 cellspacing=0 cellpadding=2><thead><tr bgcolor=\"#F0F0F0\">";
for (int column = 0; column < columnCount; column++) {
// Headers
if (!treeView->isColumnHidden(column))
out << QString("<th>%1</th>").arg(model->headerData(column, Qt::Horizontal).toString().toHtmlEscaped());
}
out << "</tr></thead>";
for (int column = 0; column < columnCount; column++) {
QModelIndex groupIndex = model->index(row, column, treeView->rootIndex());
// A row for the object name
for (int rowChild = 0; rowChild < model->rowCount(groupIndex); rowChild++) {
QModelIndex objectIndex = model->index(rowChild, column, groupIndex);
out << "<tr>";
for (int column2 = 0; column2 < columnCount; column2++) {
if (!treeView->isColumnHidden(column2)) {
QModelIndex cellIndex = model->index(rowChild, column2, groupIndex);
QString data = model->data(cellIndex).toString().toHtmlEscaped();
out << QString("<td><h2>%1</h2></td>").arg((!data.isEmpty()) ? data : QString("&nbsp;"));
}
}
out << "</tr>";
// One row for each object's fields
for (int rowChild2 = 0; rowChild2 < model->rowCount(objectIndex); rowChild2++) {
out << "<tr>";
for (int column2 = 0; column2 < columnCount; column2++) {
if (!treeView->isColumnHidden(column2)) {
QModelIndex fieldIndex = model->index(rowChild2, column2, objectIndex);
QString data = model->data(fieldIndex).toString().toHtmlEscaped();
out << QString("<td>%1</td>").arg((!data.isEmpty()) ? data : QString("&nbsp;"));
}
}
out << "</tr>";
}
}
}
out << "</table>";
}
out << "</body></html>";
QTextDocument *document = new QTextDocument();
document->setHtml(strStream);
QPrinter printer;
QPrintDialog *dialog = new QPrintDialog(&printer);
if (dialog->exec() == QDialog::Accepted)
document->print(&printer);
delete dialog;
delete document;
}

View File

@@ -300,6 +300,7 @@ private slots:
void exportFilteredTable();
void updateInsertDeleteRecordButton();
void runSqlNewTab(const QString& query, const QString& title);
void printDbStructure();
};
#endif

View File

@@ -56,6 +56,7 @@
<addaction name="editCreateIndexAction"/>
<addaction name="editModifyObjectAction"/>
<addaction name="editDeleteObjectAction"/>
<addaction name="actionDbPrint"/>
</widget>
</item>
<item>
@@ -2315,6 +2316,33 @@ You can drag SQL statements from the Schema column and drop them into the SQL ed
<enum>Qt::WidgetShortcut</enum>
</property>
</action>
<action name="actionDbPrint">
<property name="enabled">
<bool>false</bool>
</property>
<property name="icon">
<iconset resource="icons/icons.qrc">
<normaloff>:/icons/print</normaloff>:/icons/print</iconset>
</property>
<property name="text">
<string>Print</string>
</property>
<property name="toolTip">
<string>Print the structure of the opened database [Ctrl+P]</string>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string>Open a dialog for printing the structure of the opened database</string>
</property>
<property name="shortcut">
<string>Ctrl+P</string>
</property>
<property name="shortcutContext">
<enum>Qt::WidgetShortcut</enum>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
@@ -3696,6 +3724,22 @@ You can drag SQL statements from the Schema column and drop them into the SQL ed
</hint>
</hints>
</connection>
<connection>
<sender>actionDbPrint</sender>
<signal>triggered()</signal>
<receiver>MainWindow</receiver>
<slot>printDbStructure()</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>518</x>
<y>314</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>fileOpen()</slot>