1+ #include " QConnectionCtrl.h"
2+
3+ QConnectionCtrl::QConnectionCtrl (QWidget* parent) {
4+ QTreeWidgetItem* rootItem = new QTreeWidgetItem ();
5+ rootItem->setIcon (0 , QApplication::style ()->standardIcon (QStyle::SP_ComputerIcon));
6+ rootItem->setText (0 , tr (" Databases" ));
7+ setHeaderItem (rootItem);
8+
9+ setMinimumSize (250 , 252 );
10+ setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding);
11+ setFrameStyle (QFrame::Panel | QFrame::Sunken);
12+ setLineWidth (2 );
13+
14+ QAction* refreshAction = new QAction (tr (" Refresh" ), this );
15+ QAction* shemaAction = new QAction (tr (" Show shema" ), this );
16+ shemaAction->setEnabled (false );
17+ shemaAction->setObjectName (" shemaAction" );
18+ QAction* separator = new QAction;
19+ separator->setSeparator (true );
20+ QAction* addConnectionAction = new QAction (tr (" Add Connection..." ), this );
21+
22+ connect (refreshAction, &QAction::triggered, this , [=]() { refresh (); });
23+ connect (shemaAction, &QAction::triggered, this , &QConnectionCtrl::showMetaData);
24+ connect (addConnectionAction, &QAction::triggered, this , &QConnectionCtrl::showConnectionDialog);
25+
26+ addAction (refreshAction);
27+ addAction (shemaAction);
28+ addAction (separator);
29+ addAction (addConnectionAction);
30+ setContextMenuPolicy (Qt::ActionsContextMenu);
31+
32+ connect (this , &QTreeWidget::itemActivated, [=](QTreeWidgetItem* item, int column) {setActiveItem (item, column); });
33+ connect (this , &QTreeWidget::currentItemChanged, [=](QTreeWidgetItem* current, QTreeWidgetItem* previous) {
34+ findChild<QAction*>(" shemaAction" )->setEnabled (current && current->parent ());
35+ });
36+
37+ setObjectName (" connectionCtrl" );
38+
39+ emit statusMessage (tr (" Ready." ));
40+ }
41+
42+ QSqlError QConnectionCtrl::createConnection (const QString& driver, const QString& dbName, const QString& host, const QString& user, const QString& passwd, const int port) {
43+ static int cCount = 0 ;
44+ QSqlDatabase db = QSqlDatabase::addDatabase (driver, QString (" dbConnection%1" ).arg (++cCount));
45+ db.setDatabaseName (dbName);
46+ db.setHostName (host);
47+ db.setPort (port);
48+
49+ QSqlError err;
50+ if (!db.open (user, passwd)) {
51+ err = db.lastError ();
52+ db = QSqlDatabase ();
53+ QSqlDatabase::removeDatabase (QString (" dbConnection%1" ).arg (cCount));
54+ }
55+
56+ return err;
57+ }
58+
59+ void QConnectionCtrl::addConnection (const QString& driver, const QString& dbName, const QString& host, const QString& user, const QString& passwd, const int port) {
60+ QSqlError err = createConnection (driver, dbName, host, user, passwd, port);
61+ if (err.type () != QSqlError::NoError)
62+ QMessageBox::warning (this , tr (" Unable to open database" ), tr (" An error occurred while "
63+ " opening the connection: " ) + err.text ());
64+ else refresh ();
65+ }
66+
67+ void QConnectionCtrl::showConnectionDialog () {
68+ QConnectionDialog dialog (this );
69+ connect (&dialog, &QConnectionDialog::connectionAdded, this , &QConnectionCtrl::addConnection);
70+ dialog.exec ();
71+ }
72+
73+ void QConnectionCtrl::showMetaData () {
74+ QTreeWidgetItem* cItem = currentItem ();
75+ if (!cItem || !cItem->parent ())
76+ return ;
77+ setActiveDb (cItem->parent ());
78+
79+ QString t = cItem->text (0 );
80+
81+ QSqlRecord rec = QSqlDatabase::database (m_activeDb).record (t);
82+ QStandardItemModel* model = new QStandardItemModel (nullptr );
83+
84+ model->insertRows (0 , rec.count ());
85+ model->insertColumns (0 , 7 );
86+
87+ model->setHeaderData (0 , Qt::Horizontal, " Fieldname" );
88+ model->setHeaderData (1 , Qt::Horizontal, " Type" );
89+ model->setHeaderData (2 , Qt::Horizontal, " Length" );
90+ model->setHeaderData (3 , Qt::Horizontal, " Precision" );
91+ model->setHeaderData (4 , Qt::Horizontal, " Required" );
92+ model->setHeaderData (5 , Qt::Horizontal, " AutoValue" );
93+ model->setHeaderData (6 , Qt::Horizontal, " DefaultValue" );
94+
95+ for (int i = 0 ; i < rec.count (); ++i) {
96+ QSqlField fld = rec.field (i);
97+ model->setData (model->index (i, 0 ), fld.name ());
98+ model->setData (model->index (i, 1 ), fld.typeID () == -1
99+ ? QString (fld.metaType ().name ())
100+ : QString (" %1 (%2)" ).arg (fld.metaType ().name ()).arg (fld.typeID ()));
101+ model->setData (model->index (i, 2 ), fld.length ());
102+ model->setData (model->index (i, 3 ), fld.precision ());
103+ model->setData (model->index (i, 4 ), fld.requiredStatus () == -1 ? QVariant (" ?" )
104+ : QVariant (bool (fld.requiredStatus ())));
105+ model->setData (model->index (i, 5 ), fld.isAutoValue ());
106+ model->setData (model->index (i, 6 ), fld.defaultValue ());
107+ }
108+
109+ emit tableModelChanged (model, QAbstractItemView::NoEditTriggers);
110+ }
111+
112+ void QConnectionCtrl::setActiveItem (QTreeWidgetItem* item, int column) {
113+ if (!item)
114+ return ;
115+
116+ if (item->parent ()) {
117+ setActiveDb (item->parent ());
118+
119+ const QString t = item->text (0 );
120+ QSqlDatabase db = QSqlDatabase::database (m_activeDb);
121+
122+ QSqlTableModel* model = new CustomModel (nullptr , db);
123+ model->setEditStrategy (QSqlTableModel::OnRowChange);
124+ model->setTable (db.driver ()->escapeIdentifier (t, QSqlDriver::TableName));
125+ model->select ();
126+ if (model->lastError ().type () != QSqlError::NoError)
127+ emit statusMessage (model->lastError ().text ());
128+
129+ emit tableModelChanged (model, QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed);
130+ }
131+ else setActiveDb (item);
132+ }
133+
134+ void QConnectionCtrl::refresh () {
135+ clear ();
136+ QStringList connectionNames = QSqlDatabase::connectionNames ();
137+
138+ bool gotActiveDb = false ;
139+ for (int i = 0 ; i < connectionNames.count (); ++i) {
140+ QTreeWidgetItem* rootItem = new QTreeWidgetItem (this );
141+ QSqlDatabase db = QSqlDatabase::database (connectionNames.at (i), false );
142+
143+ QString dbCaption = db.driverName ();
144+ dbCaption.append (QLatin1Char (' :' ));
145+ if (!db.userName ().isEmpty ())
146+ dbCaption.append (db.userName ()).append (QLatin1Char (' @' ));
147+ dbCaption.append (db.databaseName ());
148+
149+ rootItem->setText (0 , dbCaption);
150+ rootItem->setIcon (0 , QApplication::style ()->standardIcon (QStyle::SP_DriveNetIcon));
151+ if (connectionNames.at (i) == QSqlDatabase::database (m_activeDb).connectionName ()) {
152+ gotActiveDb = true ;
153+ setActiveDb (rootItem);
154+ }
155+ if (db.isOpen ()) {
156+ QStringList tableList = db.tables ();
157+ for (int t = 0 ; t < tableList.count (); ++t) {
158+ QTreeWidgetItem* table = new QTreeWidgetItem (rootItem);
159+ table->setText (0 , tableList.at (t));
160+ table->setIcon (0 , QApplication::style ()->standardIcon (QStyle::SP_DirOpenIcon));
161+ }
162+ }
163+ }
164+ if (!gotActiveDb) {
165+ m_activeDb = connectionNames.value (0 );
166+ setActiveDb (topLevelItem (0 ));
167+ }
168+
169+ doItemsLayout ();
170+ }
171+
172+ void QConnectionCtrl::setActiveDb (QTreeWidgetItem* item) {
173+ auto f_setBold = [=](QTreeWidgetItem* item, bool bold) {
174+ QFont font = item->font (0 );
175+ font.setBold (bold);
176+ item->setFont (0 , font);
177+ };
178+
179+ for (int i = 0 ; i < topLevelItemCount (); ++i) {
180+ if (topLevelItem (i)->font (0 ).bold ())
181+ f_setBold (topLevelItem (i), false );
182+ }
183+
184+ if (!item)
185+ return ;
186+
187+ f_setBold (item, true );
188+ m_activeDb = QSqlDatabase::connectionNames ().value (indexOfTopLevelItem (item));
189+ }
0 commit comments