|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2009 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing a widget showing the SQL connections. |
|
8 """ |
|
9 |
|
10 from __future__ import unicode_literals |
|
11 |
|
12 from PyQt5.QtCore import pyqtSignal, Qt |
|
13 from PyQt5.QtWidgets import QWidget, QHeaderView, QTreeWidget, QVBoxLayout, \ |
|
14 QTreeWidgetItem, QAction |
|
15 from PyQt5.QtSql import QSqlDatabase |
|
16 |
|
17 from Globals import qVersionTuple |
|
18 |
|
19 |
|
20 class SqlConnectionWidget(QWidget): |
|
21 """ |
|
22 Class implementing a widget showing the SQL connections. |
|
23 |
|
24 @signal tableActivated(str) emitted after the entry for a table has been |
|
25 activated |
|
26 @signal schemaRequested(str) emitted when the schema display is requested |
|
27 @signal cleared() emitted after the connection tree has been cleared |
|
28 """ |
|
29 tableActivated = pyqtSignal(str) |
|
30 schemaRequested = pyqtSignal(str) |
|
31 cleared = pyqtSignal() |
|
32 |
|
33 def __init__(self, parent=None): |
|
34 """ |
|
35 Constructor |
|
36 |
|
37 @param parent reference to the parent widget (QWidget) |
|
38 """ |
|
39 super(SqlConnectionWidget, self).__init__(parent) |
|
40 |
|
41 layout = QVBoxLayout(self) |
|
42 layout.setContentsMargins(0, 0, 0, 0) |
|
43 |
|
44 self.__connectionTree = QTreeWidget(self) |
|
45 self.__connectionTree.setObjectName("connectionTree") |
|
46 self.__connectionTree.setHeaderLabels([self.tr("Database")]) |
|
47 if qVersionTuple() >= (5, 0, 0): |
|
48 self.__connectionTree.header().setSectionResizeMode( |
|
49 QHeaderView.Stretch) |
|
50 else: |
|
51 self.__connectionTree.header().setResizeMode(QHeaderView.Stretch) |
|
52 refreshAction = QAction(self.tr("Refresh"), self.__connectionTree) |
|
53 self.__schemaAction = QAction( |
|
54 self.tr("Show Schema"), self.__connectionTree) |
|
55 |
|
56 refreshAction.triggered.connect(self.refresh) |
|
57 self.__schemaAction.triggered.connect(self.showSchema) |
|
58 |
|
59 self.__connectionTree.addAction(refreshAction) |
|
60 self.__connectionTree.addAction(self.__schemaAction) |
|
61 self.__connectionTree.setContextMenuPolicy(Qt.ActionsContextMenu) |
|
62 |
|
63 layout.addWidget(self.__connectionTree) |
|
64 |
|
65 self.__activating = False |
|
66 |
|
67 self.__connectionTree.itemActivated.connect(self.__itemActivated) |
|
68 self.__connectionTree.currentItemChanged.connect( |
|
69 self.__currentItemChanged) |
|
70 |
|
71 self.__activeDb = "" |
|
72 |
|
73 def refresh(self): |
|
74 """ |
|
75 Public slot to refresh the connection tree. |
|
76 """ |
|
77 self.__connectionTree.clear() |
|
78 self.cleared.emit() |
|
79 |
|
80 connectionNames = QSqlDatabase.connectionNames() |
|
81 |
|
82 foundActiveDb = False |
|
83 for name in connectionNames: |
|
84 root = QTreeWidgetItem(self.__connectionTree) |
|
85 db = QSqlDatabase.database(name, False) |
|
86 root.setText(0, self.__dbCaption(db)) |
|
87 if name == self.__activeDb: |
|
88 foundActiveDb = True |
|
89 self.__setActive(root) |
|
90 if db.isOpen(): |
|
91 tables = db.tables() |
|
92 for table in tables: |
|
93 itm = QTreeWidgetItem(root) |
|
94 itm.setText(0, table) |
|
95 |
|
96 if not foundActiveDb and connectionNames: |
|
97 self.__activeDb = connectionNames[0] |
|
98 self.__setActive(self.__connectionTree.topLevelItem(0)) |
|
99 |
|
100 def showSchema(self): |
|
101 """ |
|
102 Public slot to show schema data of a database. |
|
103 """ |
|
104 cItm = self.__connectionTree.currentItem() |
|
105 if cItm is None or cItm.parent() is None: |
|
106 return |
|
107 self.__setActive(cItm.parent()) |
|
108 self.schemaRequested.emit(cItm.text(0)) |
|
109 |
|
110 def __itemActivated(self, itm, column): |
|
111 """ |
|
112 Private slot handling the activation of an item. |
|
113 |
|
114 @param itm reference to the item (QTreeWidgetItem) |
|
115 @param column column that was activated (integer) |
|
116 """ |
|
117 if itm is None: |
|
118 return |
|
119 |
|
120 if not self.__activating: |
|
121 self.__activating = True |
|
122 if itm.parent() is None: |
|
123 self.__setActive(itm) |
|
124 else: |
|
125 self.__setActive(itm.parent()) |
|
126 self.tableActivated.emit(itm.text(0)) |
|
127 self.__activating = False |
|
128 |
|
129 def __currentItemChanged(self, current, previous): |
|
130 """ |
|
131 Private slot handling a change of the current item. |
|
132 |
|
133 @param current reference to the new current item (QTreeWidgetItem) |
|
134 @param previous reference to the previous current item |
|
135 (QTreeWidgetItem) |
|
136 """ |
|
137 self.__schemaAction.setEnabled( |
|
138 current is not None and current.parent() is not None) |
|
139 |
|
140 def __dbCaption(self, db): |
|
141 """ |
|
142 Private method to assemble a string for the caption. |
|
143 |
|
144 @param db reference to the database object (QSqlDatabase) |
|
145 @return caption string (string) |
|
146 """ |
|
147 nm = db.driverName() |
|
148 nm += ":" |
|
149 if db.userName(): |
|
150 nm += db.userName() |
|
151 nm += "@" |
|
152 nm += db.databaseName() |
|
153 return nm |
|
154 |
|
155 def __setBold(self, itm, bold): |
|
156 """ |
|
157 Private slot to set the font to bold. |
|
158 |
|
159 @param itm reference to the item to be changed (QTreeWidgetItem) |
|
160 @param bold flag indicating bold (boolean) |
|
161 """ |
|
162 font = itm.font(0) |
|
163 font.setBold(bold) |
|
164 itm.setFont(0, font) |
|
165 |
|
166 def currentDatabase(self): |
|
167 """ |
|
168 Public method to get the current database. |
|
169 |
|
170 @return reference to the current database (QSqlDatabase) |
|
171 """ |
|
172 return QSqlDatabase.database(self.__activeDb) |
|
173 |
|
174 def __setActive(self, itm): |
|
175 """ |
|
176 Private slot to set an item to active. |
|
177 |
|
178 @param itm reference to the item to set as the active item |
|
179 (QTreeWidgetItem) |
|
180 """ |
|
181 for index in range(self.__connectionTree.topLevelItemCount()): |
|
182 if self.__connectionTree.topLevelItem(index).font(0).bold(): |
|
183 self.__setBold( |
|
184 self.__connectionTree.topLevelItem(index), False) |
|
185 |
|
186 if itm is None: |
|
187 return |
|
188 |
|
189 self.__setBold(itm, True) |
|
190 self.__activeDb = QSqlDatabase.connectionNames()[ |
|
191 self.__connectionTree.indexOfTopLevelItem(itm)] |