EmuFront ... NOT Foobar :D
[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 as published by
9 // the Free Software Foundation, either version 3 of the License, or
10 // (at your option) any later version.
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 explicitically delete widgets within a parented layout
49     // they are automatically parented and will be deleted
50     // dbManager is also parented and will be implicitically deleted
51     // this must be deleted in an implementing class
52     //delete dbObject;
53 }
54
55 void DbObjectDialog::connectSignals()
56 {
57     qDebug() << "DbObjectDialog connecting signals";
58     connect(buttonBox, SIGNAL(accepted()), this, SLOT(close()));
59     connect(objectList, SIGNAL(clicked(const QModelIndex &)),
60         this, SLOT(listObjectClicked(const QModelIndex &)));
61     connect(editButton, SIGNAL(clicked()), this, SLOT(editButtonClicked()));
62     connect(addButton, SIGNAL(clicked()), this, SLOT(addButtonClicked()));
63     connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteButtonClicked()));
64     connect(nameDialog, SIGNAL(dataObjectUpdated()), this, SLOT(updateData()));
65     connect(nameDialog, SIGNAL(updateRejected()), this, SLOT(updateReject()));
66     connect(nameDialog, SIGNAL(test()), this, SLOT(testSlot()));
67 }
68     
69 void DbObjectDialog::testSlot()
70 {
71     qDebug() << "TEST SIGNAL RECEIVED!";
72 }
73
74 void DbObjectDialog::insertDb(const EmuFrontObject *ob) const
75 {
76     if (!dbManager->insertDataObjectToModel(ob))
77         errorMessage->showMessage(tr("Inserting data object %1 failed.").arg(ob->getName()));
78 }
79
80 void DbObjectDialog::addObject()
81 {
82     if (!nameDialog) initEditDialog();
83     deleteCurrentObject();
84     dbObject = createObject();
85     nameDialog->setDataObject(dbObject);
86     activateNameDialog();
87 }
88
89 void DbObjectDialog::editObject()
90 {
91     QModelIndex index = objectList->currentIndex();
92     if (!index.isValid())
93         return;
94     if (!nameDialog) initEditDialog();
95     deleteCurrentObject();
96     dbObject = dbManager->getDataObjectFromModel(&index);
97     nameDialog->setDataObject(dbObject);
98     activateNameDialog();
99 }
100
101 bool DbObjectDialog::deleteItem()
102 {
103     QModelIndex index = objectList->currentIndex();
104     if (!index.isValid()) return false;
105     try
106     {
107         EmuFrontObject *ob = dbManager->getDataObjectFromModel(&index);
108
109         if (!ob)
110         {
111             errorMessage->showMessage(tr("Couldn't find the selected data object from data model!"));
112             return false;
113         }
114
115         int numBindings = dbManager->countDataObjectRefs(ob->getId());
116
117         if (numBindings > 0 && !confirmDelete(ob->getName(), numBindings))
118         { return false; }
119         deleteCurrentObject();
120
121         bool delOk = dbManager->deleteDataObjectFromModel(&index);
122         if (!delOk)
123         {
124             errorMessage->showMessage(tr("Deleting data object %1 failed!").arg(ob->getName()));
125             return false;
126         }
127         updateList();
128         objectList->setFocus();
129     }
130     catch(EmuFrontException e)
131     {
132         errorMessage->showMessage(e.what());
133     }
134     return false;
135 }
136
137 void DbObjectDialog::updateDb(const EmuFrontObject *ob) const
138 {
139     if (!ob) return;
140     if ( !dbManager->updateDataObjectToModel(ob) )
141     { errorMessage->showMessage("Database update failed!"); }
142 }
143
144 void DbObjectDialog::updateList() const
145 {
146     if (!dbManager) return;
147     dbManager->resetModel();
148 }
149
150 void DbObjectDialog::addButtonClicked()
151 {
152     disableSelection();
153     addObject();
154 }
155
156 void DbObjectDialog::editButtonClicked()
157 {
158     disableSelection();
159     editObject();
160 }
161
162 void DbObjectDialog::deleteButtonClicked()
163 {
164     QItemSelectionModel *selModel = objectList->selectionModel();
165     if (!selModel->hasSelection()) return;
166
167     QAbstractItemModel *tblModel = objectList->model();
168     QModelIndex index = selModel->currentIndex();
169     QVariant vName = tblModel->data(index);
170     QString name = vName.toString();
171     disableSelection();
172
173     QString msg =  tr("Do you want to delete") + name + "?";
174     int yn = QMessageBox::question(this, "Confirm", msg, QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
175     if (yn == QMessageBox::Yes)
176     {
177         deleteItem();
178     }
179 }
180
181 void DbObjectDialog::layout()
182 {
183     QHBoxLayout *mainLayout = new QHBoxLayout;
184     mainLayout->addWidget(objectList);
185     mainLayout->addWidget(buttonBox);
186     setLayout(mainLayout);
187 }
188
189 void DbObjectDialog::listObjectClicked(const QModelIndex &index)
190 {
191     const QModelIndex *x;
192     x = &index;
193     qDebug() << "Row " << x->row() << ", column " << x->column() << " clicked.";
194     setButtonsEnabled(index.isValid());
195     if(!index.isValid()) 
196         return;
197 }
198
199 void DbObjectDialog::setButtonsEnabled(bool enabled)
200 {
201     editButton->setEnabled(enabled);
202     deleteButton->setEnabled(enabled);
203 }
204
205 void DbObjectDialog::disableSelection()
206 {
207     setButtonsEnabled(false);
208 }
209
210 void DbObjectDialog::activateNameDialog()
211 {
212     if (!nameDialog) return;
213     nameDialog->show();
214     nameDialog->raise();
215     nameDialog->activateWindow();
216 }
217
218 void DbObjectDialog::initDataTable()
219 {
220    objectList->setModel(dbManager->getDataModel());
221    objectList->setSelectionMode(QAbstractItemView::SingleSelection);
222    objectList->resizeColumnsToContents();
223 }
224
225 void DbObjectDialog::updateReject()
226 {
227     // we don't want to keep this in memory
228     deleteCurrentObject();
229 }
230
231 void DbObjectDialog::updateData()
232 {
233     // update data model
234     if (!dbObject) return;
235
236     // if data object id > -1 we are updating the data otherwise we are inserting new data
237     if (dbObject->getId() > -1) updateDb(dbObject);
238     else insertDb(dbObject);
239
240     // we don't need dbObject anymore
241     deleteCurrentObject();
242     dbObject = 0;
243     updateList();
244 }
245
246 void DbObjectDialog::deleteCurrentObject()
247 {
248     delete dbObject;
249 }
250
251 bool DbObjectDialog::confirmDelete(QString name, int numRefs)
252 {
253     int r = QMessageBox::warning(this, tr("Confirm delete"),
254                                  QString("Do you really want to delete %1 with %2 data bindings?")
255                                  .arg(name).arg(numRefs),
256                                  QMessageBox::Yes | QMessageBox::No);
257     if ( r == QMessageBox::No )
258         return false;
259     return true;
260 }
261
262 void DbObjectDialog::refreshDataModel()
263 {
264     dbManager->resetModel();
265 }