From e2916da12c7309ded63c3d091271ebb2f9123305 Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Sun, 2 Dec 2012 21:30:41 -0600 Subject: [PATCH] Added some basic functionality to the program. Changes include: Being able to add a vendor, layout tweaks to the main window, vendor browsing, and probably a bunch of other stuff that I don't remember. So let this be a lesson to you: commit often, and be sure to document those changesets! --- src/about.cpp | 25 +++----- src/contacteditwidget.cpp | 23 +++++++- src/contacteditwidget.h | 8 +++ src/mainwin.cpp | 121 +++++++++++++++++++++++++++++++++++++- src/scmwidget.cpp | 106 +++++++++++++++++++++++++++++++-- src/scmwidget.h | 22 ++++++- src/vendorclassdialog.cpp | 28 +++++++++ src/vendorlevelwidget.cpp | 5 ++ 8 files changed, 311 insertions(+), 27 deletions(-) diff --git a/src/about.cpp b/src/about.cpp index 86d3ac2..8d81d0a 100644 --- a/src/about.cpp +++ b/src/about.cpp @@ -14,6 +14,7 @@ #include "about.h" //#include "version.h" + AboutWindow::AboutWindow(QWidget * parent/*= 0*/): QWidget(parent, Qt::Dialog) { setWindowTitle(tr("About SCheMatic...")); @@ -22,13 +23,12 @@ AboutWindow::AboutWindow(QWidget * parent/*= 0*/): QWidget(parent, Qt::Dialog) layout->setSizeConstraint(QLayout::SetFixedSize); setLayout(layout); - image = new QLabel(); - image->setAlignment(Qt::AlignRight); - image->setPixmap(QPixmap(":/res/schematic.png")); - layout->addWidget(image); - QString s; s.append(tr( + "

" + "" + "SCheMatic
" + "The Supply Chain Manager-O-Matic

" "" "" "" "" -// "" -// "" "
Version: " // VJ_RELEASE_VERSION " (" VJ_RELEASE_SUBVERSION ")" @@ -36,29 +36,20 @@ AboutWindow::AboutWindow(QWidget * parent/*= 0*/): QWidget(parent, Qt::Dialog) "
Coders: James \"Shamus\" Hammons
Testers: Jason O'Neal
Build Team: ggn (win32)
LinkoVitch, goldenegg (MacOS)
Homepage: http://icculus.org/virtualjaguar/
" "

" "The SCheMatic team would like to express their gratitude to:" "

" - "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
" -// "Ryan C. Gordon for Virtual Jaguar's web presence
" -// "Curt Vendel for various Jaguar & other goodies (you rock!)
" -// "Reboot for reasons too numerous to mention
" -// "The Free Jaguar Project (you know why) ;-)
" -// "The guys over at Atari Age :-)
" -// "byuu for BSNES and showing us what was possible" + "Everyone who helped make SCheMatic a reality.

" )); text = new QLabel(s); layout->addWidget(text); } + void AboutWindow::keyPressEvent(QKeyEvent * e) { if (e->key() == Qt::Key_Escape || e->key() == Qt::Key_Return) hide(); } + diff --git a/src/contacteditwidget.cpp b/src/contacteditwidget.cpp index 110a8c7..e709596 100644 --- a/src/contacteditwidget.cpp +++ b/src/contacteditwidget.cpp @@ -20,10 +20,12 @@ ContactEditWidget::ContactEditWidget(QWidget * parent/*= 0*/): QWidget(parent), field4(new QLineEdit), field5(new QLineEdit), field6(new QLineEdit), - field7(new QLineEdit) + field7(new QLineEdit), + newContactType(false) { QFormLayout * form = new QFormLayout; + field1->setEditable(true); form->addRow(tr("Type:"), field1); form->addRow(tr("Name:"), field2); form->addRow(tr("Email:"), field3); @@ -33,5 +35,24 @@ ContactEditWidget::ContactEditWidget(QWidget * parent/*= 0*/): QWidget(parent), form->addRow(tr("Fax:"), field7); setLayout(form); + + connect(field1, SIGNAL(editTextChanged(const QString &)), this, SLOT(NewItem(const QString &))); + connect(field1, SIGNAL(highlighted(int)), this, SLOT(ExistingItem(int))); +} + + +// Here we make some assumptions: +// - If the user types something in, they probably are creating a new category. +// - If the user selects something, they probably want to use an existing one. + +void ContactEditWidget::NewItem(const QString &) +{ + newContactType = true; +} + + +void ContactEditWidget::ExistingItem(int) +{ + newContactType = false; } diff --git a/src/contacteditwidget.h b/src/contacteditwidget.h index d9e1c46..581604d 100644 --- a/src/contacteditwidget.h +++ b/src/contacteditwidget.h @@ -12,9 +12,15 @@ class ContactEditWidget: public QWidget { + Q_OBJECT + public: ContactEditWidget(QWidget * parent = 0); + protected slots: + void NewItem(const QString &); + void ExistingItem(int); + public: QComboBox * field1; QLineEdit * field2; @@ -23,6 +29,8 @@ class ContactEditWidget: public QWidget QLineEdit * field5; QLineEdit * field6; QLineEdit * field7; + + bool newContactType; }; #endif // __CONTACTEDITWIDGET_H__ diff --git a/src/mainwin.cpp b/src/mainwin.cpp index 55ba367..fc1ec2f 100644 --- a/src/mainwin.cpp +++ b/src/mainwin.cpp @@ -26,7 +26,6 @@ MainWindow::MainWindow(): aboutWin(new AboutWindow(this)), - scmWidget(new SCMWidget(this)), boldFont(new QFont), loggedInUID(0) { @@ -196,6 +195,7 @@ MainWindow::MainWindow(): aboutWin(new AboutWindow(this)), loggedInUID = 1; } + scmWidget = new SCMWidget(this); QString s = QString("User: %1 (%2)").arg(fullName).arg(login); scmWidget->username->setText(s); setCentralWidget(scmWidget); @@ -248,10 +248,125 @@ void MainWindow::HandleNewVendorDialog(void) // Presumably, the user has given us good data, so we try to populate the // database with this new vendor data. - QSqlQuery query; - query.prepare("INSERT INTO VALUES (?, ?, ?)"); + // First, see if there is anything missing from the dialog... + + // Create new vendor entry... + int vid = -1; + bool hasNDA = (dialog.checkbox1->checkState() == Qt::Checked ? true : false); + int vlid = dialog.combo1->itemData(dialog.combo1->currentIndex()).toInt(); + QSqlQuery query; + query.prepare("INSERT INTO Vendor VALUES ('', ?, ?, ?)"); + query.addBindValue(vlid); + query.addBindValue(hasNDA); + query.addBindValue(dialog.edit1->text()); + query.exec(); + + // Get VID from record just inserted + query.prepare("SELECT vid FROM Vendor WHERE vlid=? AND signedNDA=? AND name=?"); + query.addBindValue(vlid); + query.addBindValue(hasNDA); + query.addBindValue(dialog.edit1->text()); + query.exec(); + query.next(); + vid = query.value(0).toInt(); +//printf("NVD: New Vendor VID=%i\n", vid); + + // Add primary address... + query.prepare("INSERT INTO Location VALUES ('', ?, ?, ?, ?, ?, ?)"); + query.addBindValue(vid); + query.addBindValue(dialog.address->field1->text()); + query.addBindValue(dialog.address->field2->text()); + query.addBindValue(dialog.address->field3->text()); + query.addBindValue(dialog.address->field4->text()); + query.addBindValue(dialog.address->field5->text()); + query.exec(); + + // Fix up primary contact type + int ctid = -1; + + // -1 in currentIndex() means nothing was selected, so create new entry +//NOT SO FAST: Seems it defaults to whatever is found there. So need to fix that. >:-( +// if (dialog.contact->field1->currentIndex() == -1) + if (dialog.contact->newContactType) + { + query.prepare("INSERT INTO ContactType VALUES ('', ?)"); + query.addBindValue(dialog.contact->field1->currentText()); + query.exec(); + + query.prepare("SELECT ctid FROM ContactType WHERE description=?"); + query.addBindValue(dialog.contact->field1->currentText()); + query.exec(); + query.next(); + ctid = query.value(0).toInt(); + } + else + { + ctid = dialog.contact->field1->itemData(dialog.contact->field1->currentIndex()).toInt(); + } + + // Add primary contact... + query.prepare("INSERT INTO Contact VALUES ('', ?, ?, ?, ?, ?, ?, ?, ?)"); + query.addBindValue(vid); + query.addBindValue(ctid); + query.addBindValue(dialog.contact->field2->text()); + query.addBindValue(dialog.contact->field3->text()); + query.addBindValue(dialog.contact->field4->text()); + query.addBindValue(dialog.contact->field5->text()); + query.addBindValue(dialog.contact->field6->text()); + query.addBindValue(dialog.contact->field7->text()); + query.exec(); + + // Add vendor classes... + for(int i=0; icount(); i++) + { + QListWidgetItem * item = dialog.list->item(i); + + if (item->checkState() == Qt::Checked) + { + int vtid = item->data(Qt::UserRole).toInt(); + query.prepare("INSERT INTO VendorSpecificTypes VALUES (?, ?)"); + query.addBindValue(vid); + query.addBindValue(vtid); + query.exec(); + } + } + + // Update UI + scmWidget->GetVendorIDs(); + scmWidget->GetVendor(vid); + +//printf("NVD: Contact Type index = %i\n", dialog.contact->field1->currentIndex()); +//printf("NVD: Contact type ='%s'\n", dialog.contact->field1->currentText().toAscii().data()); +//-1 means no contact selected; check currentText() to see if it has anything in it or not + + // Tables to fill: +#if 0 +Vendor +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; + +VendorType +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; + +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 | 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 +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; + +ContactType +CTID (P-key) | Description +CREATE TABLE ContactType (ctid INT NOT NULL PRIMARY KEY AUTO_INCREMENT, description VARCHAR(100)) ENGINE=INNODB; +#endif } diff --git a/src/scmwidget.cpp b/src/scmwidget.cpp index 78f757f..07b9cd1 100644 --- a/src/scmwidget.cpp +++ b/src/scmwidget.cpp @@ -12,6 +12,7 @@ // #include "scmwidget.h" +#include #include "addresswidget.h" #include "contactwidget.h" @@ -27,6 +28,9 @@ SCMWidget::SCMWidget(QWidget * parent/*= 0*/): QWidget(parent), vendorLevel(new VendorLevelWidget), alerts(new QListWidget), notes(new QListWidget), + vaw1(new AddressWidget(this)), + vcw1(new ContactWidget(this)), + nextVendorButton(new QToolButton), previousVendorButton(new QToolButton), editVendor(new QPushButton("Edit Vendor")), @@ -38,7 +42,9 @@ SCMWidget::SCMWidget(QWidget * parent/*= 0*/): QWidget(parent), showOpen(new QPushButton("Open")), showClosed(new QPushButton("Closed")), showAll(new QPushButton("All")), - createPO(new QPushButton("Create")) + createPO(new QPushButton("Create")), + vendorRelated(new QCheckBox("Related to this Vendor")), + vidCursor(0) { // Create main page widgets & layout @@ -100,15 +106,13 @@ SCMWidget::SCMWidget(QWidget * parent/*= 0*/): QWidget(parent), // Vendor address widgets - AddressWidget * vaw1 = new AddressWidget(this); - vaw1->SetFields("123 Any Street", "Any City", "Anywhere", "USA", "01234"); +// vaw1->SetFields("123 Any Street", "Any City", "Anywhere", "USA", "01234"); vendorAddress->addTab(vaw1, tr("Primary")); vendorAddress->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); // Vendor contact widgets - ContactWidget * vcw1 = new ContactWidget(this); - vcw1->SetFields("Sales", "Joe Blow", "joe.blow@widget.com", "Singapore", "512-222-2222", "", "512-122-2123"); +// vcw1->SetFields("Sales", "Joe Blow", "joe.blow@widget.com", "Singapore", "512-222-2222", "", "512-122-2123"); vendorContact->addTab(vcw1, tr("Contact #1")); vendorContact->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); @@ -163,6 +167,8 @@ SCMWidget::SCMWidget(QWidget * parent/*= 0*/): QWidget(parent), hbox6->addWidget(showOpen); hbox6->addWidget(showClosed); hbox6->addWidget(showAll); + hbox6->addSpacing(16); + hbox6->addWidget(vendorRelated); hbox6->addStretch(); hbox6->addWidget(createPO); @@ -200,5 +206,95 @@ SCMWidget::SCMWidget(QWidget * parent/*= 0*/): QWidget(parent), mainLayout->addLayout(hbox6); mainLayout->addWidget(purchaseOrders); setLayout(mainLayout); + + // Set up actions + + connect(nextVendorButton, SIGNAL(clicked()), this, SLOT(GetNextVendor())); + connect(previousVendorButton, SIGNAL(clicked()), this, SLOT(GetPreviousVendor())); + + GetVendorIDs(); + GetVendor(vendorID[vidCursor]); +} + + +void SCMWidget::GetNextVendor(void) +{ + if (vidCursor < (vendorID.size() - 1)) + { + vidCursor++; + GetVendor(vendorID[vidCursor]); + } +} + + +void SCMWidget::GetPreviousVendor(void) +{ + if (vidCursor > 0) + { + vidCursor--; + GetVendor(vendorID[vidCursor]); + } +} + + +void SCMWidget::GetVendorIDs(void) +{ + vendorID.clear(); + + QSqlQuery query; + query.prepare("SELECT vid FROM Vendor ORDER BY name"); + query.exec(); + + while (query.next()) + { + int vid = query.value(0).toInt(); + vendorID.push_back(vid); + } +} + + +void SCMWidget::GetVendor(int key) +{ + // Get main vendor data + QSqlQuery query; + query.prepare("SELECT v.name, signedNDA, l.address, city, state, country, code, " + "c.name, email, c.address, phone1, phone2, fax, description, v.vlid FROM " + "Vendor AS v LEFT OUTER JOIN Location AS l ON v.vid = l.vid " + "LEFT OUTER JOIN (Contact AS c JOIN ContactType AS ct ON c.ctid = ct.ctid) " + "ON v.vid = c.vid WHERE v.vid = ?"); + query.addBindValue(key); + query.exec(); + + // There's a possibility that the query will return multiple rows (which we need + // to handle, with multiple tabs), but for now, we ignore any and grab the first. + if (query.next()) + { + vendorName->setText(query.value(0).toString()); + + vaw1->SetFields(query.value(2).toString(), + query.value(3).toString(), query.value(4).toString(), + query.value(5).toString(), query.value(6).toString()); + vcw1->SetFields(query.value(13).toString(), + query.value(7).toString(), query.value(8).toString(), + query.value(9).toString(), query.value(10).toString(), + query.value(11).toString(), query.value(12).toString()); + + int vlid = query.value(14).toInt(); + vendorLevel->DoQuery(vlid); + } + + // Get vendor classes + query.prepare("SELECT description FROM VendorSpecificTypes AS vst, VendorType AS vt " + "WHERE vst.vid = ? AND vst.vtid = vt.vtid ORDER BY seqNo"); + query.addBindValue(key); + query.exec(); + + vendorClass->clear(); + + while (query.next()) + { + QListWidgetItem * item = new QListWidgetItem(query.value(0).toString()); + vendorClass->addItem(item); + } } diff --git a/src/scmwidget.h b/src/scmwidget.h index 6081f71..d29e5ad 100644 --- a/src/scmwidget.h +++ b/src/scmwidget.h @@ -9,15 +9,28 @@ #define __SCMWIDGET_H__ #include +#include #include "vendorlevelwidget.h" +class AddressWidget; +class ContactWidget; + class SCMWidget: public QWidget { + Q_OBJECT + public: SCMWidget(QWidget * parent = 0); // protected: // void keyPressEvent(QKeyEvent *); + protected slots: + void GetNextVendor(void); + void GetPreviousVendor(void); + + public: + void GetVendorIDs(void); + void GetVendor(int); public: QTreeView * purchaseOrders; @@ -30,8 +43,10 @@ class SCMWidget: public QWidget VendorLevelWidget * vendorLevel; QListWidget * alerts; QListWidget * notes; + AddressWidget * vaw1; + ContactWidget * vcw1; - private: +// private: QToolButton * nextVendorButton; QToolButton * previousVendorButton; QPushButton * editVendor; @@ -44,6 +59,11 @@ class SCMWidget: public QWidget QPushButton * showClosed; QPushButton * showAll; QPushButton * createPO; + QCheckBox * vendorRelated; + + private: + std::vector vendorID; + int vidCursor; }; #endif // __SCMWIDGET_H__ diff --git a/src/vendorclassdialog.cpp b/src/vendorclassdialog.cpp index ba670b9..61fe7b5 100644 --- a/src/vendorclassdialog.cpp +++ b/src/vendorclassdialog.cpp @@ -214,5 +214,33 @@ void VendorClassDialog::LoadList(void) void VendorClassDialog::SaveList(void) { +#if 0 +We need to do a few things here. One approach is to drop the VendorGroup and VendorType +tables and recreate them, but that approach might cause VendorSpecificTypes to contain +invalid data. + +Another approach is to keep track of keys (vgid for VendorGroup items, vtid & vgid for +VendorType items) and do an update for items with keys, and a regular add for items +that don't have keys (items that the user added to the dialog). That approach will keep +VendorSpecificTypes from being corrupted, but requires more overhead in the tracking +department. + +One way to track those items would be to put the array # into the user data area; that +way when we get here we can query that data to determine if there's keys associated with +an entry or not and how to handle it. Unfortunately, we're already using the user data +role to determine whether or not an item is a header. But we could fix that by giving +it a number and using that number as an index into oldList--but that wouldn't work for +new items! :-P + +So maybe the correct approach is to compare what's in the ListWidget with what's in +oldList, that way we can ignore things that didn't change. But what about those that did? +In that case, you're screwed. + +It would still be useful to do that in order to detect the case where the user deleted +something and then changed his mind and put it back. + + +#endif + } diff --git a/src/vendorlevelwidget.cpp b/src/vendorlevelwidget.cpp index f91b43b..0bf3001 100644 --- a/src/vendorlevelwidget.cpp +++ b/src/vendorlevelwidget.cpp @@ -76,5 +76,10 @@ void VendorLevelWidget::ParseDescription(void) { level->setText(description.left(1)); topLine->setText(description.mid(2)); + + char hexDigits[16]; + sprintf(hexDigits, "%06X", color); + QString s = QString("QLabel { background-color: #%1; }").arg(hexDigits); + level->setStyleSheet(s); } -- 2.37.2