2 // mainwin.cpp - The Supply Chain Manager-O-Matic
4 // (C) 2012 Underground Software
6 // JLH = James Hammons <jlhamm@acm.org>
9 // --- ---------- -------------------------------------------------------------
10 // JLH 09/14/2012 Created this file
13 // Uncomment this for debugging...
15 //#define DEBUGFOO // Various tool debugging...
16 //#define DEBUGTP // Toolpalette debugging...
20 #include "configdialog.h"
21 #include "logindialog.h"
22 #include "newvendordialog.h"
23 #include "scmwidget.h"
24 #include "sqlsettingsdialog.h"
25 #include "vendorclassdialog.h"
28 MainWindow::MainWindow(): aboutWin(new AboutWindow(this)),
32 setWindowIcon(QIcon(":/res/schematic.png"));
33 setWindowTitle("SCheMatic");
35 setUnifiedTitleAndToolBarOnMac(true);
39 quitAppAct = new QAction(tr("E&xit"), this);
40 quitAppAct->setShortcut(QKeySequence(tr("Ctrl+q")));
41 quitAppAct->setStatusTip(tr("Quit SCheMatic"));
42 connect(quitAppAct, SIGNAL(triggered()), this, SLOT(close()));
44 aboutAct = new QAction(QIcon(":/res/schematic.png"), tr("&About..."), this);
45 aboutAct->setStatusTip(tr("Blatant self-promotion"));
46 connect(aboutAct, SIGNAL(triggered()), this, SLOT(ShowAboutWin()));
48 configAct = new QAction(QIcon(":/res/schematic.png"), tr("&Configure..."), this);
49 configAct->setStatusTip(tr("Configure SCheMatic"));
50 connect(configAct, SIGNAL(triggered()), this, SLOT(HandleConfigDialog()));
52 vendorClassAct = new QAction(QIcon(":/res/schematic.png"), tr("&Edit Vendor Classes..."), this);
53 vendorClassAct->setStatusTip(tr("Edit Vendor Classes"));
54 connect(vendorClassAct, SIGNAL(triggered()), this, SLOT(HandleVendorClassDialog()));
56 newVendorAct = new QAction(QIcon(":/res/schematic.png"), tr("&Add Vendor..."), this);
57 newVendorAct->setStatusTip(tr("Create a new vendor"));
58 connect(newVendorAct, SIGNAL(triggered()), this, SLOT(HandleNewVendorDialog()));
60 // helpAct = new QAction(QIcon(":/res/vj-icon.png"), tr("&Contents..."), this);
61 // helpAct->setStatusTip(tr("Help is available, if you should need it"));
62 // connect(helpAct, SIGNAL(triggered()), this, SLOT(ShowHelpWin()));
64 // Create menus & toolbars
66 QMenu * menu = menuBar()->addMenu(tr("&File"));
67 // fileMenu->addAction(powerAct);
68 // fileMenu->addAction(pauseAct);
69 // fileMenu->addAction(frameAdvanceAct);
70 // fileMenu->addAction(filePickAct);
71 // fileMenu->addAction(useCDAct);
72 // fileMenu->addAction(configAct);
73 menu->addAction(quitAppAct);
75 menu = menuBar()->addMenu(tr("&Edit"));
76 menu->addAction(configAct);
77 menu->addAction(vendorClassAct);
78 menu->addAction(newVendorAct);
80 menu = menuBar()->addMenu(tr("&Help"));
81 // menu->addAction(helpAct);
82 menu->addAction(aboutAct);
84 QToolBar * toolbar = addToolBar(tr("Stuff"));
85 // toolbar->addAction(powerAct);
86 // toolbar->addAction(pauseAct);
87 // toolbar->addAction(filePickAct);
88 // toolbar->addAction(useCDAct);
89 // toolbar->addSeparator();
90 // toolbar->addAction(x1Act);
91 // toolbar->addAction(x2Act);
92 // toolbar->addAction(x3Act);
93 // toolbar->addSeparator();
94 // toolbar->addAction(ntscAct);
95 // toolbar->addAction(palAct);
96 // toolbar->addSeparator();
97 // toolbar->addAction(blurAct);
98 // toolbar->addAction(fullScreenAct);
101 statusBar()->showMessage(tr("Ready"));
104 boldFont->setBold(true);
106 // Finally, set up database connection
108 db = QSqlDatabase::addDatabase("QODBC");
111 // Prime the SQL Settings dialog (in case we need it)
113 SQLSettingsDialog sqlSettings;
114 sqlSettings.edit1->setText(dbDriver);
115 sqlSettings.edit2->setText(dbHostName);
116 sqlSettings.edit3->setText(dbName);
117 sqlSettings.edit4->setText(dbUserName);
118 sqlSettings.edit5->setText(dbPassword);
122 // Set up the ODBC DB connection with saved settings
123 // NB: For this to work properly on 64-bit Windows, you need to use the 32-bit driver!
124 QString odbc = QString("DRIVER={%1};DATABASE=%2;SERVER=%3;UID=%4;PASSWORD=%5")
125 .arg(dbDriver).arg(dbName).arg(dbHostName).arg(dbUserName).arg(dbPassword);
126 db.setDatabaseName(odbc);
129 // If unsuccessful, run the SQL settings/test dialog
132 sqlSettings.error1->setText(db.lastError().databaseText());
133 sqlSettings.error2->setText(db.lastError().driverText());
135 if (sqlSettings.exec())
137 // User thinks this will work (hit OK button), so prime the variables
138 // for the next attempt
139 dbDriver = sqlSettings.edit1->text();
140 dbHostName = sqlSettings.edit2->text();
141 dbName = sqlSettings.edit3->text();
142 dbUserName = sqlSettings.edit4->text();
143 dbPassword = sqlSettings.edit5->text();
146 return; // User cancelled the dialog, so quit
151 // Check to see how many users are in the system; if less than 2, we don't do a login
153 query.prepare("SELECT COUNT(*) FROM User");
157 if (query.value(0).toInt() > 1)
160 LoginDialog loginDlg;
165 bool accept = loginDlg.exec();
167 // Check to see if user cancelled out
172 // Search DB for this username/login pair
174 query.prepare("SELECT UID, name, login FROM User WHERE Login=? AND Password=?");
175 query.addBindValue(loginDlg.edit1->text());
176 query.addBindValue(loginDlg.edit2->text());
182 loggedInUID = query.value(0).toInt();
183 fullName = query.value(1).toString();
184 login = query.value(2).toString();
193 fullName = "Administrator";
198 scmWidget = new SCMWidget(this);
199 QString s = QString("User: %1 (%2)").arg(fullName).arg(login);
200 scmWidget->username->setText(s);
201 scmWidget->currentUID = loggedInUID;
202 scmWidget->UpdateNotes();
203 setCentralWidget(scmWidget);
207 void MainWindow::closeEvent(QCloseEvent * event)
210 event->accept(); // ignore() if can't close for some reason
214 void MainWindow::Open(void)
219 void MainWindow::ShowAboutWin(void)
225 void MainWindow::HandleConfigDialog(void)
227 ConfigDialog dialog(this);
232 void MainWindow::HandleVendorClassDialog(void)
234 VendorClassDialog dialog(this);
241 void MainWindow::HandleNewVendorDialog(void)
243 NewVendorDialog dialog(this);
244 FillVendorLevelCombo(dialog.combo1);
245 FillContactTypeCombo(dialog.contact->field1);
246 FillVendorClassList(dialog.list);
251 // Presumably, the user has given us good data, so we try to populate the
252 // database with this new vendor data.
254 // First, see if there is anything missing from the dialog...
257 // Create new vendor entry...
259 bool hasNDA = (dialog.checkbox1->checkState() == Qt::Checked ? true : false);
260 int vlid = dialog.combo1->itemData(dialog.combo1->currentIndex()).toInt();
262 query.prepare("INSERT INTO Vendor VALUES ('', ?, ?, ?)");
263 query.addBindValue(vlid);
264 query.addBindValue(hasNDA);
265 query.addBindValue(dialog.edit1->text());
268 // Get VID from record just inserted
269 query.prepare("SELECT vid FROM Vendor WHERE vlid=? AND signedNDA=? AND name=?");
270 query.addBindValue(vlid);
271 query.addBindValue(hasNDA);
272 query.addBindValue(dialog.edit1->text());
275 vid = query.value(0).toInt();
276 //printf("NVD: New Vendor VID=%i\n", vid);
278 // Add primary address...
279 query.prepare("INSERT INTO Location VALUES ('', ?, ?, ?, ?, ?, ?)");
280 query.addBindValue(vid);
281 query.addBindValue(dialog.address->field1->text());
282 query.addBindValue(dialog.address->field2->text());
283 query.addBindValue(dialog.address->field3->text());
284 query.addBindValue(dialog.address->field4->text());
285 query.addBindValue(dialog.address->field5->text());
288 // Fix up primary contact type
291 // -1 in currentIndex() means nothing was selected, so create new entry
292 //NOT SO FAST: Seems it defaults to whatever is found there. So need to fix that. >:-(
293 // if (dialog.contact->field1->currentIndex() == -1)
294 if (dialog.contact->newContactType)
296 query.prepare("INSERT INTO ContactType VALUES ('', ?)");
297 query.addBindValue(dialog.contact->field1->currentText());
300 query.prepare("SELECT ctid FROM ContactType WHERE description=?");
301 query.addBindValue(dialog.contact->field1->currentText());
304 ctid = query.value(0).toInt();
308 ctid = dialog.contact->field1->itemData(dialog.contact->field1->currentIndex()).toInt();
311 // Add primary contact...
312 query.prepare("INSERT INTO Contact VALUES ('', ?, ?, ?, ?, ?, ?, ?, ?)");
313 query.addBindValue(vid);
314 query.addBindValue(ctid);
315 query.addBindValue(dialog.contact->field2->text());
316 query.addBindValue(dialog.contact->field3->text());
317 query.addBindValue(dialog.contact->field4->text());
318 query.addBindValue(dialog.contact->field5->text());
319 query.addBindValue(dialog.contact->field6->text());
320 query.addBindValue(dialog.contact->field7->text());
323 // Add vendor classes...
324 for(int i=0; i<dialog.list->count(); i++)
326 QListWidgetItem * item = dialog.list->item(i);
328 if (item->checkState() == Qt::Checked)
330 int vtid = item->data(Qt::UserRole).toInt();
331 query.prepare("INSERT INTO VendorSpecificTypes VALUES (?, ?)");
332 query.addBindValue(vid);
333 query.addBindValue(vtid);
339 scmWidget->GetVendorIDs();
340 scmWidget->GetVendor(vid);
342 //printf("NVD: Contact Type index = %i\n", dialog.contact->field1->currentIndex());
343 //printf("NVD: Contact type ='%s'\n", dialog.contact->field1->currentText().toAscii().data());
344 //-1 means no contact selected; check currentText() to see if it has anything in it or not
349 VID (P-key) | VLID | signedNDA | Name
350 CREATE TABLE Vendor (vid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, vlid INT, signedNDA TINYINT(1) NOT NULL DEFAULT 0, name VARCHAR(100), FOREIGN KEY (vlid) REFERENCES VendorLevel(vlid)) ENGINE=INNODB;
353 VTID (P-key) | VGID | SeqNo | Description
354 CREATE TABLE VendorType (vtid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, vgid INT, seqNo INT(4) NOT NULL, description VARCHAR(100), FOREIGN KEY (vgid) REFERENCES VendorGroup(vgid)) ENGINE=INNODB;
357 VID (multi) | VTID (multi)
358 CREATE TABLE VendorSpecificTypes (vid INT, vtid INT, FOREIGN KEY (vid) REFERENCES Vendor(vid), FOREIGN KEY (vtid) REFERENCES VendorType(vtid)) ENGINE=INNODB;
361 LID (P-key) | VID | Address | City | State | Country | Code
362 CREATE TABLE Location (lid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, vid INT, address VARCHAR(100), city VARCHAR(64), state VARCHAR(64), country VARCHAR(64), code VARCHAR(32), FOREIGN KEY (vid) REFERENCES Vendor(vid)) ENGINE=INNODB;
365 CID (P-key) | VID | CTID | Name | Email | Address | Phone1 | Phone2 | Fax
366 CREATE TABLE Contact (cid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, vid INT, CTID int, name VARCHAR(64), email VARCHAR(64), address VARCHAR(200), phone1 VARCHAR(32), phone2 VARCHAR(32), fax VARCHAR(32), FOREIGN KEY (vid) REFERENCES Vendor(vid), FOREIGN KEY (ctid) REFERENCES ContactType(ctid)) ENGINE=INNODB;
369 CTID (P-key) | Description
370 CREATE TABLE ContactType (ctid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, description VARCHAR(100)) ENGINE=INNODB;
375 void MainWindow::FillVendorLevelCombo(QComboBox * combo)
378 query.prepare("SELECT VLID, Description FROM VendorLevel");
383 int vlid = query.value(0).toInt();
384 QString description = query.value(1).toString();
386 combo->addItem(description, vlid);
391 void MainWindow::FillContactTypeCombo(QComboBox * combo)
394 query.prepare("SELECT CTID, Description FROM ContactType");
399 int ctid = query.value(0).toInt();
400 QString description = query.value(1).toString();
402 combo->addItem(description, ctid);
407 void MainWindow::FillVendorClassList(QListWidget * list)
409 std::vector<VendorType> groupList;
411 // Pull in definitions from DB for Vendor Classes/Groups
413 query1.prepare("SELECT vgid, description FROM VendorGroup ORDER BY seqNo");
416 while (query1.next())
419 v.key = query1.value(0).toInt();
420 v.description = query1.value(1).toString();
421 groupList.push_back(v);
425 query1.prepare("SELECT vtid, vgid, description FROM VendorType ORDER BY seqNo");
428 int previousID = -1, groupListIndex = 0;
429 QListWidgetItem * item;
431 while (query1.next())
434 int vtid = query1.value(0).toInt();
435 int vgid = query1.value(1).toInt();
436 QString description = query1.value(2).toString();
438 // Check to see if we need to insert new header yet.
439 // If we're not still in same group, push the next group header into the list
441 if (previousID != vgid)
443 item = new QListWidgetItem(groupList[groupListIndex].description);
444 item->setData(Qt::UserRole, groupList[groupListIndex++].key);
445 item->setFont(*boldFont);
450 item = new QListWidgetItem(description);
451 item->setData(Qt::UserRole, vtid);
452 item->setCheckState(Qt::Unchecked);
458 void MainWindow::ReadSettings(void)
460 QSettings settings("Underground Software", "SCheMatic");
461 QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
462 QSize size = settings.value("size", QSize(400, 400)).toSize();
465 // pos = settings.value("charWndPos", QPoint(0, 0)).toPoint();
466 // size = settings.value("charWndSize", QSize(200, 200)).toSize();
467 // ((TTEdit *)qApp)->charWnd->resize(size);
468 // ((TTEdit *)qApp)->charWnd->move(pos);
470 dbDriver = settings.value("dbDriver", "myodbc-5.1").toString();
471 dbHostName = settings.value("dbHostName", "localhost").toString();
472 dbName = settings.value("dbName", "schematic").toString();
473 dbUserName = settings.value("dbUserName", "scm_user").toString();
474 dbPassword = settings.value("dbPassword", "scm_user").toString();
478 void MainWindow::WriteSettings(void)
480 QSettings settings("Underground Software", "SCheMatic");
481 settings.setValue("pos", pos());
482 settings.setValue("size", size());
483 // settings.setValue("charWndPos", ((TTEdit *)qApp)->charWnd->pos());
484 // settings.setValue("charWndSize", ((TTEdit *)qApp)->charWnd->size());
486 settings.setValue("dbDriver", dbDriver);
487 settings.setValue("dbHostName", dbHostName);
488 settings.setValue("dbName", dbName);
489 settings.setValue("dbUserName", dbUserName);
490 settings.setValue("dbPassword", dbPassword);