#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); ioHandler = new DataHandler(this); harFil = false; kListe = false; pListe = false; prosjekter = false; utlop = false; oppdaterUI(); filLagret = true; QCoreApplication::setOrganizationName("Arctic Software"); QCoreApplication::setOrganizationDomain("arcticsoftware.no"); QCoreApplication::setApplicationName("Saeterprosjekt"); konstruerHistorikk(); innstillingDlg = new InnstillingDialog(this); connect(innstillingDlg, SIGNAL(rejected()), this, SLOT(barnDialogLukket())); hest = new ArbeidsHest(this); } MainWindow::~MainWindow() { delete ui; } /* on_actionNy_triggered(): * ------------------------ * * Lag en ny databasefil */ void MainWindow::on_actionNy_triggered() { QString stdSted = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); // konstruer stien ved hjelp av QFileDialog //: First string "Create new database file", second string "Database file (*.saeter) filSti = QFileDialog::getSaveFileName(this, tr("Opprett ny databasefil"), stdSted, tr("Database fil (*.saeter)")); // invokerer lagreFil fra DataHandler klassen der alle IO funksjoner ligger, kontroller om vi kan skrive til filen if (!filSti.isEmpty()) { if (!ioHandler->lagreFil(filSti, kundeKart, prosjektKart, bindinger, prosjektBindingerStempler)) { ErrorCodes error = ioHandler->getError(); switch (error) { case ErrorCodes::SKRIVEFEIL: //: First string "An error occurred" Second string "Can not create the database file. Make sure you have write access in the location you have specified" QMessageBox::critical(this, tr("Feil oppstod"), tr("Kan ikke opprette databasefilen. Kontroller at du har skriverettigheter der du har oppgitt stedet på harddisken.")); break; default: break; } } else { // Oppdaterer diverse brytere i klassen for å reflektere endringer i programmet harFil = true; filLagret = true; oppdaterTittel(); oppdaterUI(); leggFilbaneTilHistorikk(filSti); delete hest; hest = new ArbeidsHest(this); connect(hest, SIGNAL(alert(ProsjektFil,AlertConditions)), this, SLOT(varsle(ProsjektFil,AlertCondition))); hest->setTidTaging(1000); hest->settProsjekt(prosjektKart); hest->run(); } } } /* on_action_pne_triggered(): * -------------------------- * * Åpne en ny databasefil */ void MainWindow::on_action_pne_triggered() { QString stdSted = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); // konstruer stien ved hjelp av QFileDialog filSti = QFileDialog::getOpenFileName(this, tr("Åpne databasefil"), stdSted, tr("Database fil (*.saeter)")); if (!filSti.isEmpty()) { // invokerer lastFil fra DataHandler klassen der alle IO funksjoner ligger if (!ioHandler->lastFil(filSti, kundeKart, prosjektKart, bindinger, prosjektBindingerStempler)) { ErrorCodes error = ioHandler->getError(); switch (error) { case ErrorCodes::UGYLDIG_FIL: //: First string "An error occurred" Second string "This does not appear to be a valid sæterproject database file" QMessageBox::critical(this, tr("Feil oppstod"), tr("Dette ser ikke ut til å være en gyldig sæterprosjekt databasefil")); break; case ErrorCodes::APP_VERSJONSKONFLIKT: QMessageBox::critical(this, tr("Feil oppstod"), tr("Versjonskonflikt i programmet. Sjekk hjemmesiden for programvareoppdateringer før du prøver å åpne denne filen")); break; case ErrorCodes::DB_VERSJONSKONFLIKT: QMessageBox::critical(this, tr("Feil oppstod"), tr("Versjonskonflikt i databasefilen. Filen du prøver å åpne er enten en eldre eller nyere versjon av hva programmet er skrevet for å håndtere. Sjekk hjemmesiden for programvareoppdateringer før du prøver å åpne denne filen")); break; case ErrorCodes::LESEFEIL: QMessageBox::critical(this, tr("Feil oppstod"), tr("Kunne ikke lese fra disken. Sjekk at du har de nødvenige rettighetene til katalogen og/eller filen før du åpner databasen")); break; default: break; } harFil = false; filLagret = false; } else { // hvis databasefilen kan åpnes, er alt fryd og gammen. Hvis ikke kan ikke denne filen brukes // oppdater grensesnittet med antall kunder og prosjekter som er lagret i filen oppdaterTellere(); // Oppdaterer diverse brytere i klassen for å reflektere endringer i programmet harFil = true; filLagret = true; // Sjekk om kundekartoteket allerede er åpnet, hvis ikke trenger vi ikke å foreta oss noe. Hvis den er åpen må vi oppdatere tabellen if (kListe) { kundeW->lagKundeTabell(kundeKart); } else if (pListe) { // Hvis prosjektkartoteket er åpen, oppdater dette grensesnittet prosjektW->oppdaterProsjektListe(prosjektKart, bindinger, kundeKart); } leggFilbaneTilHistorikk(filSti); delete hest; hest = new ArbeidsHest(this); connect(hest, SIGNAL(alert(ProsjektFil,AlertConditions)), this, SLOT(varsle(ProsjektFil,AlertConditions))); hest->setTidTaging(1000); hest->settProsjekt(prosjektKart); hest->run(); } // oppdater grensesnittet basert på de boolske verdiene i klassen oppdaterTittel(); oppdaterUI(); } } /* on_actionLagre_triggered(): * ------------------------------ * * Lagrer endringer i databasen til fil */ void MainWindow::on_actionLagre_triggered() { // invokerer lagreFil fra DataHandler klassen der alle IO funksjoner ligger ioHandler->lagreFil(filSti, kundeKart, prosjektKart, bindinger, prosjektBindingerStempler); // Oppdaterer diverse brytere i klassen for å reflektere endringer i programmet harFil = true; filLagret = true; oppdaterTittel(); oppdaterUI(); } /* on_actionL_agre_som_triggered(): * -------------------------------- * * Lagrer en kopi av databasefilen */ void MainWindow::on_actionL_agre_som_triggered() { QString stdSted = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); // konstruer stien ved hjelp av QFileDialog filSti = QFileDialog::getSaveFileName(this, tr("Lagre gjeldende database med nytt navn"), stdSted, tr("Database fil (*.saeter)")); // invokerer lagreFil fra DataHandler klassen der alle IO funksjoner ligger, kontroller om vi kan skrive til filen if (!filSti.isEmpty()) { if (!ioHandler->lagreFil(filSti, kundeKart, prosjektKart, bindinger, prosjektBindingerStempler)) { ErrorCodes error = ioHandler->getError(); switch (error) { case ErrorCodes::SKRIVEFEIL: QMessageBox::critical(this, tr("Feil oppstod"), tr("Kan ikke opprette databasefilen. Kontroller at du har skriverettigheter der du har oppgitt stedet på harddisken.")); break; default: break; } } else { // Oppdaterer diverse brytere i klassen for å reflektere endringer i programmet harFil = true; filLagret = true; oppdaterTittel(); oppdaterUI(); delete hest; hest = new ArbeidsHest(this); connect(hest, SIGNAL(alert(ProsjektFil,AlertConditions)), this, SLOT(varsle(ProsjektFil,AlertCondition))); hest->setTidTaging(1000); hest->settProsjekt(prosjektKart); hest->run(); } } } /* oppdaterTittel(): * ------------------------ * * Oppdaterer hoved dialogboksens tittel med eventuelt full sti til en allerede åpnet database. * Hvis det er ulagrede endringer i databasen legges det til en stjerne (*) på slutten av tittelen */ void MainWindow::oppdaterTittel() { if (harFil && filLagret) { this->setWindowTitle(tr("Sæterprosjekt [%1]").arg(filSti)); } else if (harFil && !filLagret) { this->setWindowTitle(tr("Sæterprosjekt [%1]*").arg(filSti)); } else { this->setWindowTitle(tr("Sæterprosjekt")); } } /* oppdaterUI(): * ------------------------ * * Slår av/på UI elementer basert på hvorvidt vi har en åpnet og aktiv database i programmet, eller ikke */ void MainWindow::oppdaterUI() { ui->commandCustomers->setEnabled(harFil); ui->commandDeadlines->setEnabled(harFil); ui->commandProsjekter->setEnabled(harFil); ui->actionL_agre_som->setEnabled(harFil); ui->actionLagre->setEnabled(harFil); } /* oppdaterTellere(): * ------------------------ * * Fyller historikk menyen med de siste åpnede filene */ void MainWindow::konstruerHistorikk() { QSettings settings; qRegisterMetaTypeStreamOperators >("QList"); QList filHistorikkListe = settings.value("filhistorikk").value>(); if (filHistorikkListe.isEmpty()) { QAction *tomListe = new QAction(tr("Ingen filer i historikk"), this); ui->menuH_istorikk->addAction(tomListe); tomListe->setEnabled(false); } else { ui->menuH_istorikk->clear(); for (int i = 0; i < filHistorikkListe.size(); ++i) { QAction *historikkAction = new QAction(filHistorikkListe.at(i), this); connect(historikkAction, &QAction::triggered, this, [=]() { lastDatabaseFil(filHistorikkListe.at(i)); }); ui->menuH_istorikk->addAction(historikkAction); } } } /* oppdaterTellere(): * ------------------------ * * Itererer gjennom kunde og prosjektliste og teller aktive oppføringer og oppdaterer UI deretter */ void MainWindow::oppdaterTellere() { ui->labelCustomerAmountValue->setText(QString::number(tellKunder())); ui->labelProjectAmountValue->setText(QString::number(tellProsjekter())); } /* slettKundeFraKartotek(): * ------------------------ * * Sletter kunde fra kundekartoteket ved bruk av kundeNummer argumentet */ void MainWindow::slettKundeFraKartotek(int kundeNummer) { for (int i = 0; i < kundeKart.size(); ++i) { if (kundeKart.at(i).value("id").toInt() == kundeNummer) { KundeFil kunde = kundeKart.at(i); kunde.insert("active", false); kundeKart.replace(i, kunde); } } } /* erstattProsjekt(): * ------------------------ * * Erstatter eksisterende prosjektfil i kartoteket med argumentet prosjekt */ void MainWindow::erstattProsjekt(ProsjektFil prosjekt) { for (int i = 0; i < prosjektKart.count(); ++i) { if (prosjektKart.at(i).value("ordrenummer").toInt() == prosjekt.value("ordrenummer").toInt()) { prosjektKart.replace(i, prosjekt); } } filLagret = false; oppdaterTittel(); } /* leggFilbaneTilHistorikk(): * -------------------------- * * Legger ny filbane inn i historikken */ void MainWindow::leggFilbaneTilHistorikk(QString filBane) { QSettings settings; qRegisterMetaTypeStreamOperators >("QList"); QList filHistorikkListe = settings.value("filhistorikk").value>(); if (filHistorikkListe.contains(filBane)) { filHistorikkListe.removeOne(filBane); filHistorikkListe.prepend(filBane); settings.setValue("filhistorikk",QVariant::fromValue(filHistorikkListe)); } else { if (filHistorikkListe.size() > 9) filHistorikkListe.removeLast(); filHistorikkListe.prepend(filBane); settings.setValue("filhistorikk",QVariant::fromValue(filHistorikkListe)); } konstruerHistorikk(); } /* lastDatabaseFil(QString): * -------------------------- * * Åpner en database med stien fil */ void MainWindow::lastDatabaseFil(QString fil) { filSti = fil; // invokerer lastFil fra DataHandler klassen der alle IO funksjoner ligger if (!ioHandler->lastFil(filSti, kundeKart, prosjektKart, bindinger, prosjektBindingerStempler)) { ErrorCodes error = ioHandler->getError(); switch (error) { case ErrorCodes::UGYLDIG_FIL: QMessageBox::critical(this, tr("Feil oppstod"), tr("Dette ser ikke ut til å være en gyldig sæterprosjekt databasefil")); break; case ErrorCodes::APP_VERSJONSKONFLIKT: QMessageBox::critical(this, tr("Feil oppstod"), tr("Versjonskonflikt i programmet. Sjekk hjemmesiden for programvareoppdateringer før du prøver å åpne denne filen")); break; case ErrorCodes::DB_VERSJONSKONFLIKT: QMessageBox::critical(this, tr("Feil oppstod"), tr("Versjonskonflikt i databasefilen. Filen du prøver å åpne er enten en eldre eller nyere versjon av hva programmet er skrevet for å håndtere. Sjekk hjemmesiden for programvareoppdateringer før du prøver å åpne denne filen")); break; case ErrorCodes::LESEFEIL: QMessageBox::critical(this, tr("Feil oppstod"), tr("Kunne ikke lese fra disken. Sjekk at du har de nødvenige rettighetene til katalogen og/eller filen før du åpner databasen")); break; default: break; } harFil = false; filLagret = false; } else { // hvis databasefilen kan åpnes, er alt fryd og gammen. Hvis ikke kan ikke denne filen brukes // oppdater grensesnittet med antall kunder og prosjekter som er lagret i filen oppdaterTellere(); // Oppdaterer diverse brytere i klassen for å reflektere endringer i programmet harFil = true; filLagret = true; // Sjekk om kundekartoteket allerede er åpnet, hvis ikke trenger vi ikke å foreta oss noe. Hvis den er åpen må vi oppdatere tabellen if (kListe) { kundeW->lagKundeTabell(kundeKart); } else if (pListe) { // Hvis prosjektkartoteket er åpen, oppdater dette grensesnittet prosjektW->oppdaterProsjektListe(prosjektKart, bindinger, kundeKart); } leggFilbaneTilHistorikk(filSti); delete hest; hest = new ArbeidsHest(this); connect(hest, SIGNAL(alert(ProsjektFil,AlertConditions)), this, SLOT(varsle(ProsjektFil,AlertConditions))); hest->setTidTaging(1000); hest->settProsjekt(prosjektKart); hest->run(); } // oppdater grensesnittet basert på de boolske verdiene i klassen oppdaterTittel(); oppdaterUI(); } /* tellKunder(): * ------------------------ * * Teller antall aktive kunder i kartoteket og returnerer et siffer med antallet */ int MainWindow::tellKunder() { int kunder = 0; for (int i = 0; i < kundeKart.size(); ++i) { bool aktiv = kundeKart.at(i).value("active").toBool(); if (aktiv) kunder++; } return kunder; } /* tellProsjekter(): * ------------------------ * * Teller antall aktive prosjekter i kartoteket og returnerer et siffer med antallet */ int MainWindow::tellProsjekter() { int prosjekter = 0; for (int i = 0; i < prosjektKart.size(); ++i) { bool aktiv = prosjektKart.at(i).value("active").toBool(); if (aktiv) prosjekter++; } return prosjekter; } /* hentKundeIndeksPosisjon(int): * -------------------------------------- * * Denne funksjonen itererer gjennom kundekartoteket og sender indeks posisjonen i vektoren * i retur når en kundeID match eksisterer */ int MainWindow::hentKundeIndeksPosisjon(int kundeNummer) { int indeks = 0; for (int i = 0; i < kundeKart.size(); ++i) { if (kundeKart.at(i).value("id").toInt() == kundeNummer) indeks = i; } return indeks; } /* closeEvent(): * -------------------------------------- * * Denne funksjonen invokeres like før applikasjonen lukkes */ void MainWindow::closeEvent(QCloseEvent *event) { if (filLagret) { event->accept(); } else { QMessageBox bekreftBoks; bekreftBoks.setText("Bekreft avslutting"); bekreftBoks.setInformativeText(tr("Du har ulagrede endringer i databasen. Vil du lagre endringene før du avslutter?")); bekreftBoks.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); bekreftBoks.setDefaultButton(QMessageBox::Save); int svar = bekreftBoks.exec(); switch (svar) { case QMessageBox::Save: ioHandler->lagreFil(filSti, kundeKart, prosjektKart, bindinger, prosjektBindingerStempler); event->accept(); break; case QMessageBox::Discard: event->accept(); break; case QMessageBox::Cancel: event->ignore(); break; default: break; } } } /* on_action_Avslutt_triggered(): * ------------------------------ * * Avslutter programmet * * TODO: Legg til en sjekk om det er noen ulagrede endringer før programmet avsluttes. Må også lage * en event handler for vinduet i tilfelle brukeren trykker 'X' vindusknappen. En event handler * kan lages ved å basere seg på den arvede prototypen til MainWindow */ void MainWindow::on_action_Avslutt_triggered() { this->close(); } /* on_commandCustomers_clicked(): * ------------------------------ * * Setter inn kundeliste widgeten i hoved dialogboksen. */ void MainWindow::on_commandCustomers_clicked() { if (!kListe) { if (pListe) { delete prosjektW; pListe = false; } else if (utlop) { delete utlopW; utlop = false; } kundeW = new KundeWidget(this); connect(kundeW, SIGNAL(opprettKunde()), this, SLOT(visNyKundeDlg())); connect(kundeW, SIGNAL(redigerKunde(int)), this, SLOT(visRedigerKundeDlg(int))); connect(kundeW, SIGNAL(slettKunde(int)), this, SLOT(slettKunde(int))); connect(kundeW, SIGNAL(tilordneProsjekt(int)), this, SLOT(visProsjektListe(int))); connect(kundeW, SIGNAL(startSok(QString)), this, SLOT(kundeSok(QString))); ui->hovedLayout->insertWidget(0, kundeW); kundeW->lagKundeTabell(kundeKart); kundeW->show(); kListe = true; utlop = false; } } /* on_commandProsjekter_clicked(): * ------------------------------- * * Setter inn prosjektliste widgeten i hoved dialogboksen. */ void MainWindow::on_commandProsjekter_clicked() { if (!pListe) { if (kListe) { delete kundeW; kListe = false; } else if (utlop) { delete utlopW; utlop = false; } prosjektW = new ProsjektWidget(this); connect(prosjektW, SIGNAL(opprettProsjekt()), this, SLOT(visNyttProsjektDlg())); connect(prosjektW, SIGNAL(hentProsjektFil(int)), this, SLOT(sendProsjektFil(int))); connect(prosjektW, SIGNAL(redigerProsjekt(int)), this, SLOT(visRedigerProsjektDialog(int))); connect(prosjektW, SIGNAL(slettProsjekt(int)), this, SLOT(slettProsjekt(int))); connect(prosjektW, SIGNAL(settAktiv(int)), this, SLOT(settAktivInaktiv(int))); connect(prosjektW, SIGNAL(fjernKunde(int,int)), this, SLOT(fjernKundeFraProsjekt(int,int))); connect(prosjektW, SIGNAL(filtrerKunKunder(bool)), SLOT(filtrerProsjektMedKunKunder(bool))); ui->hovedLayout->insertWidget(0, prosjektW); prosjektW->oppdaterProsjektListe(prosjektKart, bindinger, kundeKart); prosjektW->show(); pListe = true; } } /* on_commandDeadlines_clicked(): * ------------------------------- * * Setter inn listen over fremtidige prosjekter widgeten inn i hoved dialogboksen. */ void MainWindow::on_commandDeadlines_clicked() { if (!utlop) { if (kListe) { delete kundeW; kListe = false; } else if (pListe) { delete prosjektW; pListe = false; } } else { delete utlopW; utlop = false; } utlopW = new UtlopWidget(this); connect(utlopW, SIGNAL(prosjektListeStarter()), this, SLOT(prosjektOppstartsListe())); connect(utlopW, SIGNAL(prosjektListeAvslutter()), this, SLOT(prosjektAvslutterListe())); connect(utlopW, SIGNAL(visProsjekt(int)), this, SLOT(hoppTilProsjekt(int))); ui->hovedLayout->insertWidget(0, utlopW); utlopW->tegnUtlopsDatoer(prosjektKart); utlopW->show(); utlop = true; } /* prosjektOppstartsListe(): * ------------------------------- * * Tegner utløpsdato tabellen på ny for å vise når prosjekter starter */ void MainWindow::prosjektOppstartsListe() { utlopW->tegnOppstartsDatoer(prosjektKart); } /* prosjektAvslutterListe(): * ------------------------------- * * Tegner utløpsdato tabellen på ny for å vise når prosjekter slutter */ void MainWindow::prosjektAvslutterListe() { utlopW->tegnUtlopsDatoer(prosjektKart); } /* hoppTilProsjekt(): * ------------------------------- * * Hopper fra utløpsdato til prosjekt widget og viser prosjektet brukeren dobbelklikket på */ void MainWindow::hoppTilProsjekt(int prosjektId) { prosjektW = new ProsjektWidget(this); connect(prosjektW, SIGNAL(opprettProsjekt()), this, SLOT(visNyttProsjektDlg())); connect(prosjektW, SIGNAL(hentProsjektFil(int)), this, SLOT(sendProsjektFil(int))); connect(prosjektW, SIGNAL(redigerProsjekt(int)), this, SLOT(visRedigerProsjektDialog(int))); connect(prosjektW, SIGNAL(slettProsjekt(int)), this, SLOT(slettProsjekt(int))); connect(prosjektW, SIGNAL(settAktiv(int)), this, SLOT(settAktivInaktiv(int))); connect(prosjektW, SIGNAL(fjernKunde(int,int)), this, SLOT(fjernKundeFraProsjekt(int,int))); connect(prosjektW, SIGNAL(filtrerKunKunder(bool)), SLOT(filtrerProsjektMedKunKunder(bool))); ui->hovedLayout->insertWidget(0, prosjektW); prosjektW->oppdaterProsjektListe(prosjektKart, bindinger, kundeKart, prosjektId); prosjektW->show(); pListe = true; delete utlopW; utlop = false; } /* visNyttProsjektDlg(): * ------------------------------- * * Viser dialogboksen for å opprette et nytt prosjekt */ void MainWindow::visNyttProsjektDlg() { nyProsjektDlg = new NyttProsjektDialog(this); connect(nyProsjektDlg, SIGNAL(leggTilProsjekt(ProsjektFil)), this, SLOT(leggTilNyttProsjekt(ProsjektFil))); connect(nyProsjektDlg, SIGNAL(rejected()), this, SLOT(barnDialogLukket())); nyProsjektDlg->opprettOrdreNr(prosjektKart.size() + 1); this->hide(); nyProsjektDlg->show(); nyProsjektDlg->setFocus(); nyProsjektDlg->activateWindow(); nyProsjektDlg->fokusStart(); } /* leggTilNyttProsjekt(): * ------------------------------- * * Lagre nytt prosjekt i prosjektarkivet og oppdater prosjektlisten */ void MainWindow::leggTilNyttProsjekt(ProsjektFil prosjekt) { prosjektKart.append(prosjekt); prosjektW->oppdaterProsjektListe(prosjektKart, bindinger, kundeKart); oppdaterTellere(); nyProsjektDlg->close(); delete nyProsjektDlg; filLagret = false; oppdaterTittel(); } /* sendProsjektFil(): * ------------------------------- * * Innvokert av hentProsjektFil og henter en prosjektfil og sender den til prosjektwidgeten */ void MainWindow::sendProsjektFil(int kartotekPlassering) { ProsjektFil aktivProsjekt = prosjektKart.at(kartotekPlassering); prosjektW->settGjeldendeProsjekt(aktivProsjekt); } /* visRedigerProsjektDialog(): * ------------------------------- * * Viser dialogboksen for å redigere et eksisterende prosjekt basert på indeksen i kartoteket */ void MainWindow::visRedigerProsjektDialog(int kartotekPlassering) { ProsjektFil prosjekt = prosjektKart.at(kartotekPlassering); redigerProsjektDlg = new RedigerProsjektDialog(this); connect(redigerProsjektDlg, SIGNAL(lagreProsjekt(ProsjektFil)), this, SLOT(lagreProsjektEndringer(ProsjektFil))); connect(redigerProsjektDlg, SIGNAL(rejected()), this, SLOT(barnDialogLukket())); redigerProsjektDlg->settProsjektFil(prosjekt); this->hide(); redigerProsjektDlg->show(); redigerProsjektDlg->setFocus(); redigerProsjektDlg->activateWindow(); redigerProsjektDlg->fokusStart(); } /* visRedigerProsjektDialog(): * ------------------------------- * * Lagre endringer i det redigerte prosjektet */ void MainWindow::lagreProsjektEndringer(ProsjektFil endringer) { for (int i = 0; i < prosjektKart.size(); ++i) { if (endringer.value("ordrenummer").toInt() == prosjektKart.at(i).value("ordrenummer").toInt()) { prosjektKart.replace(i, endringer); } } prosjektW->oppdaterProsjektListe(prosjektKart, bindinger, kundeKart); filLagret = false; oppdaterTittel(); redigerProsjektDlg->close(); delete redigerProsjektDlg; } /* slettProsjekt(): * ------------------------------- * * Sletter et prosjekt fra kartoteket. */ void MainWindow::slettProsjekt(int kartotekPlassering) { QMessageBox bekreftBoks; bekreftBoks.setText("Er du sikker?"); bekreftBoks.setInformativeText(tr("Vil du slette dette prosjektet? Kundene som eventuelt er tilknyttet prosjektet vil ikke bli slettet")); bekreftBoks.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); bekreftBoks.setDefaultButton(QMessageBox::Cancel); int svar = bekreftBoks.exec(); switch (svar) { case QMessageBox::Ok: ProsjektFil prosjekt = prosjektKart.at(kartotekPlassering); prosjekt.insert("active", false); prosjektKart.replace(kartotekPlassering, prosjekt); prosjektW->oppdaterProsjektListe(prosjektKart, bindinger, kundeKart); filLagret = false; oppdaterTittel(); oppdaterTellere(); break; } } /* settAktivInaktiv(): * ------------------------------ * * Setter et prosjekt som inaktivt (ferdig) hvis det er aktiv og motsatt */ void MainWindow::settAktivInaktiv(int kartotekPlassering) { ProsjektFil prosjekt = prosjektKart.at(kartotekPlassering); bool ferdig = prosjekt.value("ferdig").toBool(); if (ferdig) prosjekt.insert("ferdig", false); else prosjekt.insert("ferdig", true); prosjektKart.replace(kartotekPlassering, prosjekt); prosjektW->oppdaterProsjektListe(prosjektKart, bindinger, kundeKart); filLagret = false; oppdaterTittel(); } /* fjernKundeFraProsjekt(): * ------------------------------ * * Sletter bindingene en kunde har mot det valgte prosjektet */ void MainWindow::fjernKundeFraProsjekt(int prosjektKartotekPosisjon, int kundeID) { int prosjektID = prosjektKart.at(prosjektKartotekPosisjon).value("ordrenummer").toInt(); QList prosjektKundeListe = bindinger.value(prosjektID); prosjektKundeListe.removeOne(kundeID); bindinger[prosjektID] = prosjektKundeListe; prosjektW->oppdaterProsjektListe(prosjektKart, bindinger, kundeKart); filLagret = false; oppdaterTittel(); } /* filtrerProsjektMedKunKunder(): * ------------------------------ * * Tegner prosjekttreet på nytt og filtrerer og viser kun prosjekter med tilordnet kunder hvis bool = sann */ void MainWindow::filtrerProsjektMedKunKunder(bool kunKunder) { prosjektW->oppdaterProsjektListe(prosjektKart, bindinger, kundeKart, 0, kunKunder); } /* varsle(): * ------------------------------ * * Hvis et varsel er trigget av arbeidshesten, invokeres denne funksjonen */ void MainWindow::varsle(ProsjektFil prosjekt, AlertConditions kondisjon) { erstattProsjekt(prosjekt); varsleDlg = new VarsleDialog(this, kondisjon); varsleDlg->settProsjektNavn(prosjekt.value("prosjektnavn").toString()); varsleDlg->settStart(prosjekt.value("prosjektstart").toULongLong()); varsleDlg->settSlutt(prosjekt.value("prosjektslutt").toULongLong()); varsleDlg->show(); } /* mottaPostNrSted(): * ------------------------------ * * Mater inn postnr og sted i postnr tabell hashen for bruk til autoutfylling av stedsnavn */ void MainWindow::mottaPostNrSted(int postNr, QString postSted) { postStedTabell.insert(postNr, postSted); } /* splashDone(): * ------------------------------ * * Starter funksjon som trigges når alle dataene er lastet og splashscreen lukkes */ void MainWindow::splashDone() { this->show(); } /* visNyKundeDlg(): * ------------------------------ * * Viser dialogboksen for å legge til en ny kunde */ void MainWindow::visNyKundeDlg() { nyKdlg = new NyKundeDialog(this, &postStedTabell); connect(nyKdlg, SIGNAL(leggTilKunde(KundeFil)), this, SLOT(settInnNyKunde(KundeFil))); connect(nyKdlg, SIGNAL(rejected()), this, SLOT(barnDialogLukket())); nyKdlg->nyKundeId(kundeKart.size() + 1); this->hide(); nyKdlg->show(); nyKdlg->setFocus(); nyKdlg->activateWindow(); nyKdlg->startTopp(); } /* visRedigerKundeDlg(): * ---------------------------------------------------------------------- * Argumenter: (int) posisjon - posisjonen i QListen der kunden er lagret * ---------------------------------------------------------------------- * * Viser dialogboksen for å redigere en kunde */ void MainWindow::visRedigerKundeDlg(int posisjon) { redigerKdlg = new RedigerKundeDialog(this, &postStedTabell); connect(redigerKdlg, SIGNAL(oppdaterKundeFil(KundeFil)), this, SLOT(redigerKunde(KundeFil))); connect(redigerKdlg, SIGNAL(rejected()), this, SLOT(barnDialogLukket())); this->hide(); redigerKdlg->show(); redigerKdlg->setFocus(); redigerKdlg->activateWindow(); redigerKdlg->settInnGamleVerdier(kundeKart.at(hentKundeIndeksPosisjon(posisjon))); } /* settInnNyKunde(): * ------------------------------ * * Setter inn en ny kunde i kartoteket og oppdaterer tabellen i kundewidgeten */ void MainWindow::settInnNyKunde(KundeFil kunde) { if (kunde.value("fornavn").toString().isEmpty()) { nyKdlg->settFeilMelding(tr("Fornavn feltet er påkrevd")); nyKdlg->fokuserElement(UIElementer::FORNAVN); } else if (kunde.value("etternavn").toString().isEmpty()) { nyKdlg->settFeilMelding(tr("Etternavn feltet er påkrevd")); nyKdlg->fokuserElement(UIElementer::ETTERNAVN); } else { kundeKart.append(kunde); oppdaterTellere(); kundeW->lagKundeTabell(kundeKart); filLagret = false; oppdaterTittel(); nyKdlg->close(); delete nyKdlg; } } /* redigerKunde(): * ------------------------------ * * Redigerer en eksisterende kunde i kartoteket og oppdaterer tabellen i kundewidgeten */ void MainWindow::redigerKunde(KundeFil redigertKunde) { if (redigertKunde.value("fornavn").toString().isEmpty()) { redigerKdlg->settFeilMelding(tr("Fornavn feltet er påkrevd")); redigerKdlg->fokuserElement(UIElementer::FORNAVN); } else if (redigertKunde.value("etternavn").toString().isEmpty()) { redigerKdlg->settFeilMelding(tr("Etternavn feltet er påkrevd")); redigerKdlg->fokuserElement(UIElementer::ETTERNAVN); } else if (redigertKunde.value("firmanavn").toString().isEmpty()) { redigerKdlg->settFeilMelding(tr("Firmanavn feltet er påkrevd")); redigerKdlg->fokuserElement(UIElementer::FIRMANAVN); } else { for (int i = 0; i < kundeKart.size(); ++i) { if (kundeKart.at(i).value("id").toInt() == redigertKunde.value("id").toInt()) { kundeKart.replace(i, redigertKunde); } } kundeW->lagKundeTabell(kundeKart); filLagret = false; oppdaterTittel(); redigerKdlg->close(); delete redigerKdlg; } } /* slettKunde(): * ------------------------------ * * Sletter kunden fra databasen. MERK: Kunden blir ikke fysisk slettet, men blir satt til * inaktiv for å bevare konsistensen og rekkefølgen i databasen, samt kundenummer sekvens */ void MainWindow::slettKunde(int posisjon) { QMessageBox bekreftBoks; bekreftBoks.setText("Er du sikker?"); bekreftBoks.setInformativeText(tr("Vil du slette denne kunden? Prosjektdataene som eventuelt er tilknyttet, vil ikke bli slettet.")); bekreftBoks.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); bekreftBoks.setDefaultButton(QMessageBox::Cancel); int svar = bekreftBoks.exec(); switch (svar) { case QMessageBox::Ok: slettKundeFraKartotek(posisjon); kundeW->lagKundeTabell(kundeKart); filLagret = false; oppdaterTittel(); oppdaterTellere(); break; default: break; } } /* visProsjektListe(): * ------------------------------ * * Åpner dialogboksen der brukeren kan tilordne kunden til et prosjekt */ void MainWindow::visProsjektListe(int posisjon) { if (tellProsjekter() == 0) { QMessageBox::warning(this, "Ugyldig operasjon", "Prosjektkartoteket inneholder ingen prosjekter. Du får ikke tilordnet noen kunder før du har opprettet et prosjekt!"); } else { kundeProsjektDlg = new VelgKundeProsjektDialog(this); connect(kundeProsjektDlg, SIGNAL(opprettBinding(int,int)), this, SLOT(knyttProsjekt(int,int))); connect(kundeProsjektDlg, SIGNAL(rejected()), this, SLOT(barnDialogLukket())); KundeFil kunde = kundeKart.at(hentKundeIndeksPosisjon(posisjon)); int kundeID = kunde.value("id").toInt(); kundeProsjektDlg->settKundeID(kundeID); kundeProsjektDlg->hentProsjekter(prosjektKart, bindinger); this->hide(); kundeProsjektDlg->show(); kundeProsjektDlg->setFocus(); kundeProsjektDlg->activateWindow(); } } /* knyttProsjekt(): * ------------------------------ * * Oppretter en relasjon mellom kunde og prosjekt */ void MainWindow::knyttProsjekt(int kunde, int prosjekt) { QList kundeListe; QList prosjektBindinger = bindinger.keys(); if (!prosjektBindinger.contains(prosjekt)) { QHash datoStempler; datoStempler.insert("created_at", DataHandler::datoStempel()); datoStempler.insert("updated_at", DataHandler::datoStempel()); kundeListe.append(kunde); bindinger.insert(prosjekt, kundeListe); prosjektBindingerStempler.insert(prosjekt, datoStempler); } else { kundeListe = bindinger.value(prosjekt); QHash datoStempler = prosjektBindingerStempler.value(prosjekt); if (!kundeListe.contains(kunde)) { kundeListe.append(kunde); datoStempler["updated_at"] = DataHandler::datoStempel(); bindinger[prosjekt] = kundeListe; prosjektBindingerStempler[prosjekt] = datoStempler; } } kundeProsjektDlg->close(); delete kundeProsjektDlg; filLagret = false; oppdaterTittel(); QMessageBox::information(this, "Tilknyttet", tr("Kunde med kundenummer %1 er tilknyttet prosjekt med ordrenummer %2").arg(kunde).arg(prosjekt)); } /* kundeSok(): * -------------------------------------- * * Tegner kundetabellen på ny med filteret i Qstring */ void MainWindow::kundeSok(QString sok) { if (sok.isEmpty()) kundeW->lagKundeTabell(kundeKart); else kundeW->lagKundeTabell(kundeKart, true, sok); } /* on_action_Innstillinger_triggered(): * -------------------------------------- * * Åpner innstillings dialogboksen */ void MainWindow::on_action_Innstillinger_triggered() { this->hide(); innstillingDlg->show(); } /* barnDialogLukket(): * -------------------------------------- * * Denne funksjonen invokeres hver gang en underdialog lukkes */ void MainWindow::barnDialogLukket() { this->show(); } /* barnDialogLukket(): * -------------------------------------- * * Denne funksjonen invokeres hver gang en underdialog lukkes */ void MainWindow::on_actionOm_triggered() { om = new OmDialog(this); om->setVersjon(APP_VERSJON); connect(om, SIGNAL(rejected()), this, SLOT(barnDialogLukket())); this->hide(); om->show(); }