From f3116511d09acfd5b32d3412c82c4337d89f2ad9 Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Fri, 21 Sep 2012 13:29:21 -0500 Subject: [PATCH] Added a bunch of new functionality Added Vendor Class dialog, New Vendor dialog, some new UI files, and an SQL configuration dialog for the case where it hasn't been configured or misconfigured. Also new main icon. --- database-schema.txt | 24 +- new-vendor.ui | 634 ++++++++++++++++++++++++++++++++++++++ phase1.ui | 542 ++++++++++++++++++++++++-------- res/schematic.png | Bin 1529 -> 22426 bytes schematic | Bin 67377 -> 0 bytes schematic-schema.sql | 45 ++- schematic.pro | 10 +- src/about.cpp | 2 +- src/logindialog.cpp | 5 +- src/logindialog.h | 4 +- src/mainwin.cpp | 101 +++++- src/mainwin.h | 14 + src/newvendordialog.cpp | 98 ++++++ src/newvendordialog.h | 39 +++ src/sqlsettingsdialog.cpp | 44 +++ src/sqlsettingsdialog.h | 26 ++ src/vendorclassdialog.cpp | 218 +++++++++++++ src/vendorclassdialog.h | 52 ++++ vendor-classes.ui | 332 ++++++++++++++++++++ 19 files changed, 2023 insertions(+), 167 deletions(-) create mode 100644 new-vendor.ui delete mode 100755 schematic create mode 100644 src/newvendordialog.cpp create mode 100644 src/newvendordialog.h create mode 100644 src/sqlsettingsdialog.cpp create mode 100644 src/sqlsettingsdialog.h create mode 100644 src/vendorclassdialog.cpp create mode 100644 src/vendorclassdialog.h create mode 100644 vendor-classes.ui diff --git a/database-schema.txt b/database-schema.txt index a7bc741..3b5a34b 100644 --- a/database-schema.txt +++ b/database-schema.txt @@ -4,28 +4,28 @@ Supply Chain Management Database (SCheMatic: The Supply Chain Manager-O-Matic) TABLES: Vendor -VID (P-key) | VLID | Name -CREATE TABLE Vendor (vid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, vlid INT, name VARCHAR(100), FOREIGN KEY (vlid) REFERENCES VendorLevel(vlid)) ENGINE=INNODB; +VID (P-key) | VLID | signedNDA | Name +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; VendorLevel VLID (P-key) | VendorUseable | Color | Description CREATE TABLE VendorLevel (vlid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, vendorUsable TINYINT(1) NOT NULL DEFAULT 0, color INT(4), description VARCHAR(100)) ENGINE=INNODB; VendorType -VTID (P-key) | VGID | Description -CREATE TABLE VendorType (vtid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, vgid INT, description VARCHAR(100), FOREIGN KEY (vgid) REFERENCES VendorGroup(vgid)) ENGINE=INNODB; +VTID (P-key) | VGID | SeqNo | Description +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; VendorGroup -VGID (P-key) | Description -CREATE TABLE VendorGroup (vgid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, description VARCHAR(100)) ENGINE=INNODB; +VGID (P-key) | SeqNo | Description +CREATE TABLE VendorGroup (vgid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, seqNo INT(4) NOT NULL, description VARCHAR(100)) ENGINE=INNODB; VendorSpecificTypes VID (multi) | VTID (multi) CREATE TABLE VendorSpecificTypes (vid INT, vtid INT, FOREIGN KEY (vid) REFERENCES Vendor(vid), FOREIGN KEY (vtid) REFERENCES VendorType(vtid)) ENGINE=INNODB; Location -LID (P-key) | VID | Description -CREATE TABLE Location () ENGINE=INNODB; +LID (P-key) | VID | Address | City | State | Country | Code +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; Contact CID (P-key) | VID | CTID | Name | Email | Address | Phone1 | Phone2 | Fax @@ -44,12 +44,12 @@ UCID | PrivilegeLevel | Description CREATE TABLE UserClass (ucid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, privilegeLevel INT NOT NULL DEFAULT 0, description VARCHAR(100)) ENGINE=INNODB; PurchaseOrder -POID (P-key) | VID | Closed | Description -CREATE TABLE PurchaseOrder (poid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, vid INT, closed TINYINT(1) NOT NULL DEFAULT 0, description VARCHAR(200), FOREIGN KEY (vid) REFERENCES Vendor(vid)) ENGINE=INNODB; +POID (P-key) | VID | Closed | PONumber | OriginalDate | AdjustedDate | Description +CREATE TABLE PurchaseOrder (poid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, vid INT, closed TINYINT(1) NOT NULL DEFAULT 0, poNumber VARCHAR(100), originalDate DATE, adjustedDate DATE, description VARCHAR(200), FOREIGN KEY (vid) REFERENCES Vendor(vid)) ENGINE=INNODB; Documents -DID (P-key) | DTID | VID | POID | Document -CREATE TABLE Documents (did INT NOT NULL PRIMARY KEY AUTO_INCREMENT, dtid INT, vid INT, poid INT, document LONGBLOB, FOREIGN KEY (dtid) REFERENCES DocumentType(dtid), FOREIGN KEY (vid) REFERENCES Vendor(vid), FOREIGN KEY (poid) REFERENCES PurchaseOrder(poid)) ENGINE=INNODB; +DID (P-key) | DTID | VID | POID | Filename | Document +CREATE TABLE Documents (did INT NOT NULL PRIMARY KEY AUTO_INCREMENT, dtid INT, vid INT, poid INT, filename VARCHAR(256), document LONGBLOB, FOREIGN KEY (dtid) REFERENCES DocumentType(dtid)) ENGINE=INNODB; DocumentType DTID (P-key) | Description diff --git a/new-vendor.ui b/new-vendor.ui new file mode 100644 index 0000000..a6d4399 --- /dev/null +++ b/new-vendor.ui @@ -0,0 +1,634 @@ + + + Dialog + + + + 0 + 0 + 728 + 652 + + + + + 0 + 0 + + + + New Vendor + + + + + 530 + 600 + 171 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 10 + 160 + 421 + 171 + + + + Primary Location + + + + + 10 + 30 + 401 + 141 + + + + + + + Address: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + City: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + State: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + Country: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Postal Code: + + + + + + + + + + + + + 10 + 350 + 421 + 231 + + + + Primary Contact + + + + + 10 + 30 + 401 + 201 + + + + + + + Type: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Name: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + Address: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Email: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Phone 1: + + + + + + + Phone 2: + + + + + + + + + + + + + + + + Fax: + + + + + + + true + + + + + + + + + + 10 + 10 + 421 + 141 + + + + Vendor + + + + + 10 + 40 + 401 + 61 + + + + + QFormLayout::ExpandingFieldsGrow + + + + + Name: + + + + + + + + + + Level: + + + + + + + + + + + + 10 + 110 + 141 + 21 + + + + NDA Signed + + + + + + + 440 + 10 + 281 + 581 + + + + Vendor Classes + + + + + 10 + 40 + 256 + 531 + + + + + Machine + + + + + Cutter + + + Unchecked + + + + + Sheet Metal + + + Unchecked + + + + + EDM Wire + + + Unchecked + + + + + CNC + + + Unchecked + + + + + Casting + + + Unchecked + + + + + Electronic Parts + + + + + Distributor + + + Unchecked + + + + + Manufacturer + + + Unchecked + + + + + Broker Grey + + + Unchecked + + + + + Representative + + + Unchecked + + + + + Printed Circuit Boards + + + ItemIsSelectable|ItemIsDragEnabled|ItemIsEnabled + + + + + PCB + + + Unchecked + + + + + PCBA + + + Unchecked + + + + + Testing + + + Unchecked + + + + + Raw Materials + + + + + Metal + + + Unchecked + + + + + Plastic + + + Unchecked + + + + + Extruded + + + Unchecked + + + + + Lenses + + + + + Distributor + + + Unchecked + + + + + Manufacturer + + + Unchecked + + + + + Representative + + + Unchecked + + + + + Filters + + + Unchecked + + + + + Cubes + + + Unchecked + + + + + Lenses + + + Unchecked + + + + + COTS + + + + + Screws + + + Unchecked + + + + + O-Ring + + + Unchecked + + + + + Switches + + + Unchecked + + + + + Captive Fasteners + + + Unchecked + + + + + Springs & Pins + + + Unchecked + + + + + Retaining Rings + + + Unchecked + + + + + Coatings + + + + + Anodized + + + Unchecked + + + + + Nickel + + + Unchecked + + + + + Paint + + + Unchecked + + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/phase1.ui b/phase1.ui index 768c40c..380c115 100644 --- a/phase1.ui +++ b/phase1.ui @@ -7,7 +7,7 @@ 0 0 932 - 626 + 826 @@ -17,8 +17,8 @@ - 570 - 410 + 790 + 230 141 111 @@ -27,14 +27,14 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Here's some stuff to look at, isn't it purty? :-)</p></body></html> +</style></head><body style=" font-family:'Sans Serif'; font-size:8pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:9pt;">Still need Action List &amp; Notes</span></p></body></html> - 10 + 60 50 221 16 @@ -85,37 +85,11 @@ p, li { white-space: pre-wrap; } Qt::Horizontal - - - - 20 - 230 - 61 - 14 - - - - Contact1: - - - - - - 90 - 230 - 221 - 22 - - - - Title, email, phone, fax, etc. - - - 90 - 200 + 10 + 80 121 21 @@ -124,93 +98,6 @@ p, li { white-space: pre-wrap; } NDA Signed - - - - 10 - 80 - 281 - 111 - - - - - - - Address: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - City: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - State: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - - - ZIP: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - - - 20 - 250 - 61 - 14 - - - - Contact2: - - - - - - 90 - 250 - 113 - 22 - - - @@ -227,9 +114,9 @@ p, li { white-space: pre-wrap; } - 320 - 50 - 591 + 20 + 570 + 901 192 @@ -272,8 +159,8 @@ p, li { white-space: pre-wrap; } - 410 - 380 + 600 + 370 121 121 @@ -324,8 +211,8 @@ p, li { white-space: pre-wrap; } - 10 - 380 + 290 + 370 131 121 @@ -364,9 +251,9 @@ p, li { white-space: pre-wrap; } - 150 - 380 - 256 + 10 + 310 + 271 192 @@ -421,6 +308,397 @@ p, li { white-space: pre-wrap; } + + + + 10 + 110 + 271 + 181 + + + + 0 + + + + Primary + + + + + 0 + 10 + 261 + 141 + + + + + + + Address: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + City: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + State: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + Country: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Postal Code: + + + + + + + + + + + + 2nd + + + + + + + 290 + 100 + 481 + 241 + + + + 0 + + + + Contact #1 + + + + + 0 + 10 + 471 + 201 + + + + + + + Type: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Name: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + Address: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Email: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Phone 1: + + + + + + + Phone 2: + + + + + + + + + + + + + + + + Fax: + + + + + + + + + #2 + + + + + #3 + + + + + + + 10 + 50 + 21 + 25 + + + + < + + + + + + 30 + 50 + 21 + 25 + + + + > + + + + + + 740 + 360 + 171 + 161 + + + + + + + 297 + 350 + 121 + 20 + + + + Caution Advised + + + + + + 440 + 370 + 141 + 121 + + + + Vendor Actions + + + + + 20 + 90 + 106 + 25 + + + + Add Location + + + + + + 20 + 60 + 106 + 25 + + + + Add Contact + + + + + + 20 + 30 + 106 + 25 + + + + Add Vendor + + + + + + + 20 + 540 + 151 + 16 + + + + Purchase Orders + + + + + + 170 + 540 + 61 + 25 + + + + Open + + + true + + + true + + + + + + 240 + 540 + 61 + 25 + + + + Closed + + + + + + 310 + 540 + 61 + 25 + + + + All + + + + + + 20 + 510 + 701 + 16 + + + + Qt::Horizontal + + @@ -428,7 +706,7 @@ p, li { white-space: pre-wrap; } 0 0 932 - 20 + 22 diff --git a/res/schematic.png b/res/schematic.png index 2b9c7fdd15450b4de5c8338c632776ffda44aad0..d07c302ba75d57f063dda51f92ab089eb3897bfb 100644 GIT binary patch literal 22426 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 O_^2yuD^)63h5irpRi`2V literal 1529 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
" "The SCheMatic team would like to express their gratitude to:" "

" - "Tracking Point for underwriting the creation of SCheMatic
" + "Everyone who helped make SCheMatic a reality.
" // "David Raingeard for the original Virtual Jaguar sources
" // "Bernd Schmidt for his UAE 68K emulator
" // "Sam Lantinga for his amazing SDL libraries
" diff --git a/src/logindialog.cpp b/src/logindialog.cpp index fdd6ce6..e2a8018 100644 --- a/src/logindialog.cpp +++ b/src/logindialog.cpp @@ -8,14 +8,12 @@ // // WHO WHEN WHAT // --- ---------- ------------------------------------------------------------ -// JLH 06/04/2011 Created this file +// JLH 09/18/2011 Created this file #include "logindialog.h" LoginDialog::LoginDialog(QWidget * parent/*= 0*/): QDialog(parent), -// label1(new QLabel(tr("Username:"))), -// label2(new QLabel(tr("Password:"))), buttonBox(new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel)), edit1(new QLineEdit()), edit2(new QLineEdit()) @@ -30,7 +28,6 @@ LoginDialog::LoginDialog(QWidget * parent/*= 0*/): QDialog(parent), formLayout->addRow(tr("&Password:"), edit2); QVBoxLayout * mainLayout = new QVBoxLayout; -// mainLayout->addWidget(tabWidget); mainLayout->addLayout(formLayout); mainLayout->addWidget(buttonBox); setLayout(mainLayout); diff --git a/src/logindialog.h b/src/logindialog.h index d583c63..d9a1d83 100644 --- a/src/logindialog.h +++ b/src/logindialog.h @@ -12,9 +12,7 @@ class LoginDialog: public QDialog ~LoginDialog(); private: -// QLabel * label1; -// QLabel * label2; - QLabel * title; +// QLabel * title; QDialogButtonBox * buttonBox; public: diff --git a/src/mainwin.cpp b/src/mainwin.cpp index b7e1748..44161ba 100644 --- a/src/mainwin.cpp +++ b/src/mainwin.cpp @@ -16,10 +16,12 @@ //#define DEBUGTP // Toolpalette debugging... #include "mainwin.h" -#include -//#include "main.h" #include "about.h" +#include "configdialog.h" #include "logindialog.h" +#include "newvendordialog.h" +#include "sqlsettingsdialog.h" +#include "vendorclassdialog.h" MainWindow::MainWindow(): aboutWin(new AboutWindow(this)), @@ -41,6 +43,18 @@ MainWindow::MainWindow(): aboutWin(new AboutWindow(this)), aboutAct->setStatusTip(tr("Blatant self-promotion")); connect(aboutAct, SIGNAL(triggered()), this, SLOT(ShowAboutWin())); + configAct = new QAction(QIcon(":/res/schematic.png"), tr("&Configure..."), this); + configAct->setStatusTip(tr("Configure SCheMatic")); + connect(configAct, SIGNAL(triggered()), this, SLOT(HandleConfigDialog())); + + vendorClassAct = new QAction(QIcon(":/res/schematic.png"), tr("&Edit Vendor Classes..."), this); + vendorClassAct->setStatusTip(tr("Edit Vendor Classes")); + connect(vendorClassAct, SIGNAL(triggered()), this, SLOT(HandleVendorClassDialog())); + + newVendorAct = new QAction(QIcon(":/res/schematic.png"), tr("&Add Vendor..."), this); + newVendorAct->setStatusTip(tr("Create a new vendor")); + connect(newVendorAct, SIGNAL(triggered()), this, SLOT(HandleNewVendorDialog())); + // helpAct = new QAction(QIcon(":/res/vj-icon.png"), tr("&Contents..."), this); // helpAct->setStatusTip(tr("Help is available, if you should need it")); // connect(helpAct, SIGNAL(triggered()), this, SLOT(ShowHelpWin())); @@ -56,6 +70,11 @@ MainWindow::MainWindow(): aboutWin(new AboutWindow(this)), // fileMenu->addAction(configAct); menu->addAction(quitAppAct); + menu = menuBar()->addMenu(tr("&Edit")); + menu->addAction(configAct); + menu->addAction(vendorClassAct); + menu->addAction(newVendorAct); + menu = menuBar()->addMenu(tr("&Help")); // menu->addAction(helpAct); menu->addAction(aboutAct); @@ -83,17 +102,43 @@ MainWindow::MainWindow(): aboutWin(new AboutWindow(this)), // Finally, set up database connection - QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL"); - db.setHostName("localhost"); - db.setDatabaseName("schematic"); - db.setUserName("scm_user"); - db.setPassword("scm_user"); - bool ok = db.open(); + db = QSqlDatabase::addDatabase("QMYSQL"); + bool ok = false; -#warning "!!! NEED TO SET UP DB SETUP DIALOG IF CONNECTION FAILED !!!" + // Prime the SQL Settings dialog (in case we need it) + SQLSettingsDialog sqlSettings; + sqlSettings.edit1->setText(dbHostName); + sqlSettings.edit2->setText(dbName); + sqlSettings.edit3->setText(dbUserName); + sqlSettings.edit4->setText(dbPassword); -// printf("Database connection was %sopened successfully.\n", (ok ? "" : "NOT ")); + do + { + // Set up the DB connection with saved settings + db.setHostName(dbHostName); + db.setDatabaseName(dbName); + db.setUserName(dbUserName); + db.setPassword(dbPassword); + ok = db.open(); + + // If unsuccessful, run the SQL settings/test dialog + if (!ok) + { + if (sqlSettings.exec()) + { + // User thinks this will work (hit OK button), so prime the variables + // for the next attempt + dbHostName = sqlSettings.edit1->text(); + dbName = sqlSettings.edit2->text(); + dbUserName = sqlSettings.edit3->text(); + dbPassword = sqlSettings.edit4->text(); + } + else + return; // User cancelled the dialog, so quit + } + } + while (!ok); // Do Login dialog LoginDialog login; @@ -144,6 +189,31 @@ void MainWindow::ShowAboutWin(void) } +void MainWindow::HandleConfigDialog(void) +{ + ConfigDialog dialog(this); + dialog.exec(); +} + + +void MainWindow::HandleVendorClassDialog(void) +{ + VendorClassDialog dialog(this); + + if (!dialog.exec()) + return; +} + + +void MainWindow::HandleNewVendorDialog(void) +{ + NewVendorDialog dialog(this); + + if (!dialog.exec()) + return; +} + + void MainWindow::ReadSettings(void) { QSettings settings("Underground Software", "SCheMatic"); @@ -155,6 +225,11 @@ void MainWindow::ReadSettings(void) // size = settings.value("charWndSize", QSize(200, 200)).toSize(); // ((TTEdit *)qApp)->charWnd->resize(size); // ((TTEdit *)qApp)->charWnd->move(pos); + + dbHostName = settings.value("dbHostName", "localhost").toString(); + dbName = settings.value("dbName", "schematic").toString(); + dbUserName = settings.value("dbUserName", "scm_user").toString(); + dbPassword = settings.value("dbPassword", "scm_user").toString(); } @@ -165,4 +240,10 @@ void MainWindow::WriteSettings(void) settings.setValue("size", size()); // settings.setValue("charWndPos", ((TTEdit *)qApp)->charWnd->pos()); // settings.setValue("charWndSize", ((TTEdit *)qApp)->charWnd->size()); + + settings.setValue("dbHostName", dbHostName); + settings.setValue("dbName", dbName); + settings.setValue("dbUserName", dbUserName); + settings.setValue("dbPassword", dbPassword); } + diff --git a/src/mainwin.h b/src/mainwin.h index 0f4cb24..5be8fd6 100644 --- a/src/mainwin.h +++ b/src/mainwin.h @@ -9,6 +9,7 @@ #define __MAINWINDOW_H__ #include +#include class AboutWindow; @@ -26,6 +27,9 @@ class MainWindow: public QMainWindow private slots: void Open(); void ShowAboutWin(void); + void HandleConfigDialog(void); + void HandleVendorClassDialog(void); + void HandleNewVendorDialog(void); private: void ReadSettings(void); @@ -35,6 +39,16 @@ class MainWindow: public QMainWindow QAction * quitAppAct; QAction * aboutAct; + QAction * configAct; + QAction * vendorClassAct; + QAction * newVendorAct; + + QString dbHostName; + QString dbName; + QString dbUserName; + QString dbPassword; + + QSqlDatabase db; public: int loggedInUID; diff --git a/src/newvendordialog.cpp b/src/newvendordialog.cpp new file mode 100644 index 0000000..8737af3 --- /dev/null +++ b/src/newvendordialog.cpp @@ -0,0 +1,98 @@ +// +// newvendordialog.cpp: Create New Vendor dialog +// +// Part of the SCheMatic Project +// (C) 2012 Underground Software +// +// JLH = James Hammons +// +// WHO WHEN WHAT +// --- ---------- ------------------------------------------------------------ +// JLH 09/21/2012 Created this file + +#include "newvendordialog.h" + + +NewVendorDialog::NewVendorDialog(QWidget * parent/*= 0*/): QDialog(parent), + buttonBox(new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel)), + edit1(new QLineEdit), + combo1(new QComboBox), + checkbox1(new QCheckBox(tr("NDA Signed"))), + edit2(new QLineEdit), + edit3(new QLineEdit), + edit4(new QLineEdit), + edit5(new QLineEdit), + edit6(new QLineEdit), + combo2(new QComboBox), + edit7(new QLineEdit), + edit8(new QLineEdit), + edit9(new QLineEdit), + edit10(new QLineEdit), + edit11(new QLineEdit), + edit12(new QLineEdit), + list(new QListWidget) +{ + connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + QVBoxLayout * vbox1 = new QVBoxLayout; + QVBoxLayout * vbox2 = new QVBoxLayout; + QVBoxLayout * vbox3 = new QVBoxLayout; + QHBoxLayout * hbox1 = new QHBoxLayout; + + QGroupBox * gb1 = new QGroupBox(tr("Vendor")); + QGroupBox * gb2 = new QGroupBox(tr("Primary Location")); + QGroupBox * gb3 = new QGroupBox(tr("Primary Contact")); + QGroupBox * gb4 = new QGroupBox(tr("Vendor Classes")); + + QFormLayout * form1 = new QFormLayout; + QFormLayout * form2 = new QFormLayout; + QFormLayout * form3 = new QFormLayout; + + form1->addRow(tr("Name:"), edit1); + form1->addRow(tr("Level:"), combo1); + + form2->addRow(tr("Address:"), edit2); + form2->addRow(tr("City:"), edit3); + form2->addRow(tr("State:"), edit4); + form2->addRow(tr("Country:"), edit5); + form2->addRow(tr("Postal Code:"), edit6); + + form3->addRow(tr("Type:"), combo2); + form3->addRow(tr("Name:"), edit7); + form3->addRow(tr("Email:"), edit8); + form3->addRow(tr("Address:"), edit9); + form3->addRow(tr("Phone 1:"), edit10); + form3->addRow(tr("Phone 2:"), edit11); + form3->addRow(tr("Fax:"), edit12); + + vbox1->addLayout(form1); + vbox1->addWidget(checkbox1); + gb1->setLayout(vbox1); + + gb2->setLayout(form2); + + gb3->setLayout(form3); + + vbox2->addWidget(gb1); + vbox2->addWidget(gb2); + vbox2->addWidget(gb3); + + vbox3->addWidget(list); + gb4->setLayout(vbox3); + + hbox1->addLayout(vbox2); + hbox1->addWidget(gb4); + + QVBoxLayout * mainLayout = new QVBoxLayout; + mainLayout->addLayout(hbox1); + mainLayout->addWidget(buttonBox); + setLayout(mainLayout); + + setWindowTitle(tr("New Vendor")); +} + +NewVendorDialog::~NewVendorDialog() +{ +} + diff --git a/src/newvendordialog.h b/src/newvendordialog.h new file mode 100644 index 0000000..e224bb1 --- /dev/null +++ b/src/newvendordialog.h @@ -0,0 +1,39 @@ +#ifndef __NEWVENDORDIALOG_H__ +#define __NEWVENDORDIALOG_H__ + +#include + +class NewVendorDialog: public QDialog +{ + Q_OBJECT + + public: + NewVendorDialog(QWidget * parent = 0); + ~NewVendorDialog(); + + private: + QDialogButtonBox * buttonBox; + + public: + QLineEdit * edit1; + QComboBox * combo1; + QCheckBox * checkbox1; + + QLineEdit * edit2; + QLineEdit * edit3; + QLineEdit * edit4; + QLineEdit * edit5; + QLineEdit * edit6; + + QComboBox * combo2; + QLineEdit * edit7; + QLineEdit * edit8; + QLineEdit * edit9; + QLineEdit * edit10; + QLineEdit * edit11; + QLineEdit * edit12; + + QListWidget * list; +}; + +#endif // __NEWVENDORDIALOG_H__ diff --git a/src/sqlsettingsdialog.cpp b/src/sqlsettingsdialog.cpp new file mode 100644 index 0000000..30b1a53 --- /dev/null +++ b/src/sqlsettingsdialog.cpp @@ -0,0 +1,44 @@ +// +// sqlsettingsdialog.cpp: The SQL Settings dialog +// +// Part of the SCheMatic Project +// (C) 2012 Underground Software +// +// JLH = James Hammons +// +// WHO WHEN WHAT +// --- ---------- ------------------------------------------------------------ +// JLH 09/19/2012 Created this file + +#include "sqlsettingsdialog.h" + + +SQLSettingsDialog::SQLSettingsDialog(QWidget * parent/*= 0*/): QDialog(parent), + buttonBox(new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel)), + edit1(new QLineEdit()), + edit2(new QLineEdit()), + edit3(new QLineEdit()), + edit4(new QLineEdit()) +{ + connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + edit4->setEchoMode(QLineEdit::Password); + + QFormLayout * formLayout = new QFormLayout; + formLayout->addRow(tr("&MySQL Server Hostname:"), edit1); + formLayout->addRow(tr("&Database Name:"), edit2); + formLayout->addRow(tr("&Database Username:"), edit3); + formLayout->addRow(tr("&Database Password:"), edit4); + + QVBoxLayout * mainLayout = new QVBoxLayout; + mainLayout->addLayout(formLayout); + mainLayout->addWidget(buttonBox); + setLayout(mainLayout); + + setWindowTitle(tr("MySQL Server Connection")); +} + +SQLSettingsDialog::~SQLSettingsDialog() +{ +} diff --git a/src/sqlsettingsdialog.h b/src/sqlsettingsdialog.h new file mode 100644 index 0000000..e1a9c8c --- /dev/null +++ b/src/sqlsettingsdialog.h @@ -0,0 +1,26 @@ +#ifndef __SQLSETTINGSDIALOG_H__ +#define __SQLSETTINGSDIALOG_H__ + +#include + +class SQLSettingsDialog: public QDialog +{ + Q_OBJECT + + public: + SQLSettingsDialog(QWidget * parent = 0); + ~SQLSettingsDialog(); + + private: +// QLabel * title; + QPushButton * testButton; + QDialogButtonBox * buttonBox; + + public: + QLineEdit * edit1; + QLineEdit * edit2; + QLineEdit * edit3; + QLineEdit * edit4; +}; + +#endif // __SQLSETTINGSDIALOG_H__ diff --git a/src/vendorclassdialog.cpp b/src/vendorclassdialog.cpp new file mode 100644 index 0000000..aef142b --- /dev/null +++ b/src/vendorclassdialog.cpp @@ -0,0 +1,218 @@ +// +// vendorclassdialog.cpp: Vendor Class editing dialog +// +// Part of the SCheMatic Project +// (C) 2012 Underground Software +// +// JLH = James Hammons +// +// WHO WHEN WHAT +// --- ---------- ------------------------------------------------------------ +// JLH 09/20/2011 Created this file + +#include "vendorclassdialog.h" +#include + + +VendorClassDialog::VendorClassDialog(QWidget * parent/*= 0*/): QDialog(parent), + buttonBox(new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel)), + addItem(new QToolButton), + deleteItem(new QToolButton), + moveItemUp(new QToolButton), + moveItemDown(new QToolButton), + makeHeader(new QCheckBox(tr("&Heading"))), + normalFont(new QFont), + boldFont(new QFont), + list(new QListWidget) +// dbRef(db) +{ + addItem->setToolButtonStyle(Qt::ToolButtonTextOnly); + addItem->setText("+"); + addItem->setToolTip(tr("Add new vendor class or group.")); + deleteItem->setToolButtonStyle(Qt::ToolButtonTextOnly); + deleteItem->setText("-"); + deleteItem->setToolTip(tr("Delete highlighted item.")); + moveItemUp->setArrowType(Qt::UpArrow); + moveItemUp->setToolTip(tr("Move highlighted item up in the list.")); + moveItemDown->setArrowType(Qt::DownArrow); + moveItemDown->setToolTip(tr("Move highlighted item down in the list.")); + makeHeader->setToolTip(tr("Make highlighted item into a vendor group.")); +// list->setToolTip(tr("")); + + QHBoxLayout * buttonLayout = new QHBoxLayout; + buttonLayout->addWidget(addItem); + buttonLayout->addWidget(deleteItem); + buttonLayout->addWidget(moveItemUp); + buttonLayout->addWidget(moveItemDown); + buttonLayout->addStretch(); + buttonLayout->addWidget(makeHeader); + + QVBoxLayout * mainLayout = new QVBoxLayout; + mainLayout->addWidget(list); + mainLayout->addLayout(buttonLayout); + mainLayout->addWidget(buttonBox); + setLayout(mainLayout); + + setWindowTitle(tr("Vendor Class Editor")); + + connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + connect(addItem, SIGNAL(clicked()), this, SLOT(AddItem())); + connect(deleteItem, SIGNAL(clicked()), this, SLOT(DeleteItem())); + connect(moveItemUp, SIGNAL(clicked()), this, SLOT(MoveItemUp())); + connect(moveItemDown, SIGNAL(clicked()), this, SLOT(MoveItemDown())); + connect(makeHeader, SIGNAL(clicked()), this, SLOT(SetHeaderStateOnItem())); + connect(list, SIGNAL(currentRowChanged(int)), this, SLOT(CurrentRowChanged(int))); + + boldFont->setBold(true); + LoadList(); +} + + +VendorClassDialog::~VendorClassDialog() +{ +} + + +void VendorClassDialog::AddItem(void) +{ + QListWidgetItem * item = new QListWidgetItem(tr("New Vendor Class")); + item->setFlags(item->flags() | Qt::ItemIsEditable); + + // We'll have to use the setData(Qt::UserRole, bool) to set the header/no header data... + +// item->setCheckState(Qt::Unchecked); +// Qt::ItemFlags f = item->flags(); +// //nope, this doesn't work. the above fucks something up that's not unfuckable. +// f &= ~Qt::ItemIsUserCheckable; +// item->setFlags(f | Qt::ItemIsEditable); + + int row = list->row(list->currentItem()); + list->insertItem(row + 1, item); +} + + +void VendorClassDialog::DeleteItem(void) +{ + int row = list->row(list->currentItem()); + QListWidgetItem * item = list->takeItem(row); + + // This could be called on an empty list, so we have a sanity check here... + if (item) + delete item; +} + + +void VendorClassDialog::MoveItemUp(void) +{ + int row = list->row(list->currentItem()); + + if (row == 0) + return; + + QListWidgetItem * item = list->takeItem(row); + list->insertItem(row - 1, item); + list->setCurrentItem(item); +} + + +void VendorClassDialog::MoveItemDown(void) +{ + int row = list->row(list->currentItem()); + + if (row == list->count() - 1) + return; + + QListWidgetItem * item = list->takeItem(row); + list->insertItem(row + 1, item); + list->setCurrentItem(item); +} + + +void VendorClassDialog::SetHeaderStateOnItem(void) +{ + QListWidgetItem * item = list->currentItem(); + item->setData(Qt::UserRole, makeHeader->isChecked()); + + if (makeHeader->isChecked()) + item->setFont(*boldFont); + else + item->setFont(*normalFont); +} + + +void VendorClassDialog::CurrentRowChanged(int /*row*/) +{ + // Show our indicator that this item is a header/group or not + QListWidgetItem * item = list->currentItem(); + bool isHeader = item->data(Qt::UserRole).toBool(); + makeHeader->setChecked(isHeader); +} + + +// This probably should be in the mainwin class... +void VendorClassDialog::LoadList(void) +{ + std::vector groupList; + + // Pull in definitions from DB for Vendor Classes/Groups + QSqlQuery query1("SELECT vgid, seqNo, description FROM VendorGroup ORDER BY seqNo"); + query1.exec(); + + while (query1.next()) + { + VendorType v; + v.key = query1.value(0).toInt(); + v.seqNo = query1.value(1).toInt(); + v.description = query1.value(2).toString(); + v.isHeader = true; + + groupList.push_back(v); + } + + QSqlQuery query2("SELECT vtid, vgid, seqNo, description FROM VendorType ORDER BY seqNo"); + query2.exec(); + + int previousID = -1, groupListIndex = 0; + + while (query2.next()) + { + VendorType v; + v.key = query2.value(0).toInt(); + int vgid = query2.value(1).toInt(); + v.seqNo = query2.value(2).toInt(); + v.description = query2.value(3).toString(); + v.isHeader = false; + + // Check to see if we need to insert new header yet. + // If we're not still in same group, push the next group header into the list + // and continue + if (previousID != vgid) + { + oldList.push_back(groupList[groupListIndex++]); + previousID = vgid; + } + + oldList.push_back(v); + } + + // Finally, populate the QListWidget + for(int i=0; isetFlags(item->flags() | Qt::ItemIsEditable); + item->setData(Qt::UserRole, oldList[i].isHeader); + + if (oldList[i].isHeader) + item->setFont(*boldFont); + + list->insertItem(i, item); + } +} + + +void VendorClassDialog::SaveList(void) +{ +} + diff --git a/src/vendorclassdialog.h b/src/vendorclassdialog.h new file mode 100644 index 0000000..4a0b702 --- /dev/null +++ b/src/vendorclassdialog.h @@ -0,0 +1,52 @@ +#ifndef __VENDORCLASSDIALOG_H__ +#define __VENDORCLASSDIALOG_H__ + +#include +#include + +struct VendorType +{ + int key; + int seqNo; + bool isHeader; + QString description; +}; + + +class VendorClassDialog: public QDialog +{ + Q_OBJECT + + public: + VendorClassDialog(QWidget * parent = 0); + ~VendorClassDialog(); + + private slots: + void AddItem(void); + void DeleteItem(void); + void MoveItemUp(void); + void MoveItemDown(void); + void SetHeaderStateOnItem(void); + void CurrentRowChanged(int); + + private: + void LoadList(void); + void SaveList(void); + + private: + QDialogButtonBox * buttonBox; + QToolButton * addItem; + QToolButton * deleteItem; + QToolButton * moveItemUp; + QToolButton * moveItemDown; + QCheckBox * makeHeader; + std::vector oldList; + QFont * normalFont; + QFont * boldFont; + + public: + QListWidget * list; +// QSqlDatabase & dbRef; +}; + +#endif // __VENDORCLASSDIALOG_H__ diff --git a/vendor-classes.ui b/vendor-classes.ui new file mode 100644 index 0000000..0c6e050 --- /dev/null +++ b/vendor-classes.ui @@ -0,0 +1,332 @@ + + + Dialog + + + + 0 + 0 + 343 + 439 + + + + Dialog + + + + + 130 + 310 + 171 + 32 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 50 + 50 + 256 + 201 + + + + + Machine + + + + + Cutter + + + + + Sheet Metal + + + + + EDM Wire + + + + + CNC + + + + + Casting + + + + + Electronic Parts + + + + + Distributor + + + + + Manufacturer + + + + + Broker Grey + + + + + Representative + + + + + Printed Circuit Boards + + + ItemIsSelectable|ItemIsDragEnabled|ItemIsEnabled + + + + + PCB + + + + + PCBA + + + + + Testing + + + + + Raw Materials + + + + + Metal + + + + + Plastic + + + + + Extruded + + + + + Lenses + + + + + Distributor + + + + + Manufacturer + + + + + Representative + + + + + Filters + + + + + Cubes + + + + + Lenses + + + + + COTS + + + + + Screws + + + + + O-Ring + + + + + Switches + + + + + Captive Fasteners + + + + + Springs & Pins + + + + + Retaining Rings + + + + + Coatings + + + + + Anodized + + + + + Nickel + + + + + Paint + + + + + + + 50 + 260 + 251 + 31 + + + + + + + + + + + + + + + - + + + + + + + ^ + + + Qt::UpArrow + + + + + + + + + + Qt::DownArrow + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Heading + + + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + -- 2.37.2