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