Fixed a bug: When window was closed from window manager e.g. X-button,
[emufront] / src / dialogs / dbobjectdialog.cpp
1 // EmuFront
2 // Copyright 2010 Mikko Keinänen
3 //
4 // This file is part of EmuFront.
5 //
6 //
7 // EmuFront is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License version 2 as published by
9 // the Free Software Foundation and appearing in the file gpl.txt included in the
10 // packaging of this file.
11 //
12 // EmuFront is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with EmuFront.  If not, see <http://www.gnu.org/licenses/>.
19
20 #include <QtGui>
21 #include <QSqlTableModel>
22 #include "dbobjectdialog.h"
23 #include "../db/databasemanager.h"
24
25 DbObjectDialog::DbObjectDialog(QWidget *parent)
26     : EmuFrontDialog(parent)
27 {
28     dbObject = 0;
29     dbManager = 0;
30     nameDialog = 0;
31     editButton = new QPushButton(tr("&Edit")); 
32     editButton->setEnabled(false);
33     addButton = new QPushButton(tr("&Add"));
34     deleteButton = new QPushButton(tr("&Delete"));
35     deleteButton->setEnabled(false);
36     objectList = new QTableView(this);
37     buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok, Qt::Vertical);
38     buttonBox->addButton(editButton, QDialogButtonBox::ActionRole);
39     buttonBox->addButton(addButton, QDialogButtonBox::ActionRole);
40     buttonBox->addButton(deleteButton, QDialogButtonBox::ActionRole);
41     // this be called from the implementing classes:
42     //connectSignals();
43     layout();
44
45
46 DbObjectDialog::~DbObjectDialog()
47 {
48     // no need to explicitly delete widgets within a parented layout
49     // they are automatically parented and will be deleted
50     // dbManager is also parented and will be implicitly deleted
51     // this must be deleted in an implementing class
52     //delete dbObject;
53     // hiddenColumn QList will be deleted implicitly, since it
54     // implements implicit data sharing
55 }
56
57 void DbObjectDialog::connectSignals()
58 {
59     connect(buttonBox, SIGNAL(accepted()), this, SLOT(close()));
60     connect(objectList, SIGNAL(clicked(const QModelIndex &)),
61         this, SLOT(listObjectClicked(const QModelIndex &)));
62     connect(editButton, SIGNAL(clicked()), this, SLOT(editButtonClicked()));
63     connect(addButton, SIGNAL(clicked()), this, SLOT(addButtonClicked()));
64     connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteButtonClicked()));
65     connect(nameDialog, SIGNAL(dataObjectUpdated()), this, SLOT(updateData()));
66     connect(nameDialog, SIGNAL(updateRejected()), this, SLOT(updateReject()));
67     connect(nameDialog, SIGNAL(test()), this, SLOT(testSlot()));
68     connect(nameDialog, SIGNAL(dialogClosed()), this, SLOT(enableUi()));
69 }
70     
71 void DbObjectDialog::testSlot()
72 {
73     qDebug() << "TEST SIGNAL RECEIVED!";
74 }
75
76 void DbObjectDialog::insertDb(const EmuFrontObject *ob) const
77 {
78     if (!dbManager->insertDataObjectToModel(ob))
79         errorMessage->showMessage(tr("Inserting data object %1 failed.").arg(ob->getName()));
80 }
81
82 void DbObjectDialog::addObject()
83 {
84     setUIEnabled(false);
85     if (!nameDialog) initEditDialog();
86     deleteCurrentObject();
87     dbObject = createObject();
88     nameDialog->setDataObject(dbObject);
89     activateNameDialog();
90 }
91
92 void DbObjectDialog::editObject()
93 {
94     QModelIndex index = objectList->currentIndex();
95     if (!index.isValid())
96         return;
97     if (!nameDialog) initEditDialog();
98     deleteCurrentObject();
99     dbObject = dbManager->getDataObjectFromModel(&index);
100     activateNameDialog();
101     nameDialog->setDataObject(dbObject);
102 }
103
104 bool DbObjectDialog::deleteItem()
105 {
106     qDebug() << "deleteItem called";
107     QModelIndex index = objectList->currentIndex();
108     if (!index.isValid()) return false;
109     try
110     {
111         EmuFrontObject *ob = dbManager->getDataObjectFromModel(&index);
112
113         qDebug() << "Trying to delete " << ob->getName();
114
115         if (!ob)
116         {
117             errorMessage->showMessage(tr("Couldn't find the selected data object from data model!"));
118             return false;
119         }
120
121         int numBindings = dbManager->countDataObjectRefs(ob->getId());
122
123         if (numBindings > 0 && !confirmDelete(ob->getName(), numBindings))
124         { return false; }
125         deleteCurrentObject();
126
127         bool delOk = dbManager->deleteDataObject(ob->getId());
128         if (!delOk)
129         {
130             errorMessage->showMessage(tr("Deleting data object %1 failed!").arg(ob->getName()));
131             return false;
132         }
133         updateList();
134         objectList->setFocus();
135         setUIEnabled(true);
136     }
137     catch(EmuFrontException e)
138     {
139         errorMessage->showMessage(e.what());
140     }
141     return false;
142 }
143
144 void DbObjectDialog::updateDb(const EmuFrontObject *ob) const
145 {
146     if (!ob) return;
147     if ( !dbManager->updateDataObjectToModel(ob) )
148     { errorMessage->showMessage("Database update failed!"); }
149 }
150
151 void DbObjectDialog::updateList() const
152 {
153     if (!dbManager) return;
154     dbManager->resetModel();
155 }
156
157 void DbObjectDialog::addButtonClicked()
158 {
159     disableSelection();
160     addObject();
161 }
162
163 void DbObjectDialog::editButtonClicked()
164 {
165     disableSelection();
166     editObject();
167 }
168
169 void DbObjectDialog::deleteButtonClicked()
170 {
171     QItemSelectionModel *selModel = objectList->selectionModel();
172     if (!selModel->hasSelection()) return;
173
174     QAbstractItemModel *tblModel = objectList->model();
175     QModelIndex index = selModel->currentIndex();
176     QVariant vName = tblModel->data(index);
177     QString name = vName.toString();
178     disableSelection();
179
180     QString msg =  tr("Do you want to delete") + name + "?";
181     int yn = QMessageBox::question(this, "Confirm", msg, QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
182     if (yn == QMessageBox::Yes)
183     {
184         deleteItem();
185     }
186 }
187
188 void DbObjectDialog::layout()
189 {
190     QHBoxLayout *mainLayout = new QHBoxLayout;
191     mainLayout->addWidget(objectList);
192     mainLayout->addWidget(buttonBox);
193     setLayout(mainLayout);
194 }
195
196 void DbObjectDialog::listObjectClicked(const QModelIndex &index)
197 {
198     const QModelIndex *x;
199     x = &index;
200     qDebug() << "Row " << x->row() << ", column " << x->column() << " clicked.";
201     setButtonsEnabled(index.isValid());
202     if(!index.isValid()) 
203         return;
204 }
205
206 void DbObjectDialog::enableUi()
207 {
208     setUIEnabled(true);
209 }
210
211 void DbObjectDialog::setButtonsEnabled(bool enabled)
212 {
213     addButton->setEnabled(enabled);
214     editButton->setEnabled(enabled);
215     deleteButton->setEnabled(enabled);
216 }
217
218 void DbObjectDialog::setUIEnabled(bool enabled)
219 {
220     buttonBox->setEnabled(enabled);
221     objectList->setEnabled(enabled);
222 }
223
224 void DbObjectDialog::disableSelection()
225 {
226     setUIEnabled(false);
227     //setButtonsEnabled(false);
228 }
229
230 void DbObjectDialog::activateNameDialog(bool updateData)
231 {
232     if (!nameDialog) return;
233     nameDialog->show();
234     nameDialog->raise();
235     if (updateData)
236         nameDialog->updateData();
237     nameDialog->activateWindow();
238 }
239
240 void DbObjectDialog::initDataTable()
241 {
242    objectList->setModel(dbManager->getDataModel());
243    objectList->setSelectionMode(QAbstractItemView::SingleSelection);
244    objectList->resizeColumnsToContents();
245 }
246
247 void DbObjectDialog::updateReject()
248 {
249     addButton->setEnabled(true);
250     setUIEnabled(true);
251     // we don't want to keep this in memory
252     deleteCurrentObject();
253 }
254
255 void DbObjectDialog::updateData()
256 {
257     qDebug() << "DbObjectDialog::updateData()";
258     // update data model
259     if (!dbObject) return;
260
261
262     // if data object id > -1 we are updating the data otherwise we are inserting new data
263     if (dbObject->getId() > -1) updateDb(dbObject);
264     else insertDb(dbObject);
265
266     // we don't need dbObject anymore
267     deleteCurrentObject();
268     dbObject = 0;
269     updateList();
270     setUIEnabled(true);
271 }
272
273 /* Implementation specific delete must be used!
274 void DbObjectDialog::deleteCurrentObject()
275 {
276     delete dbObject;
277 }*/
278
279 bool DbObjectDialog::confirmDelete(QString name, int numRefs)
280 {
281     int r = QMessageBox::warning(this, tr("Confirm delete"),
282                                  QString("Do you really want to delete %1 with %2 data bindings?")
283                                  .arg(name).arg(numRefs),
284                                  QMessageBox::Yes | QMessageBox::No);
285     if ( r == QMessageBox::No )
286         return false;
287     return true;
288 }
289
290 void DbObjectDialog::refreshDataModel()
291 {
292     dbManager->resetModel();
293 }
294
295 void DbObjectDialog::hideColumns()
296 {
297     foreach(int c, hiddenColumns)
298         objectList->hideColumn(c);
299 }