All pastes #1992603 Raw Edit

khluurrooster.cpp

public cpp v1 · immutable
#1992603 ·published 2010-11-15 21:11 UTC
rendered paste body
/*    Copyright (c) 2010, Stijn Leenknegt    All rights reserved.    Redistribution and use in source and binary forms, with or without    modification, are permitted provided that the following conditions are met:        * Redistributions of source code must retain the above copyright        notice, this list of conditions and the following disclaimer.        * Redistributions in binary form must reproduce the above copyright        notice, this list of conditions and the following disclaimer in the        documentation and/or other materials provided with the distribution.        * Neither the name of the KHL nor the        names of its contributors may be used to endorse or promote products        derived from this software without specific prior written permission.    THIS SOFTWARE IS PROVIDED BY Stijn Leenknegt ''AS IS'' AND ANY    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE    DISCLAIMED. IN NO EVENT SHALL Stijn Leenknegt BE LIABLE FOR ANY    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/#include <QPainter>#include <QFontMetrics>#include <QSizeF>#include <KLocale>#include <QWidget>#include <QString>#include <QDir>#include <QDomDocument>#include <kconfigdialog.h>#include <kconfiggroup.h>#include <kmessagebox.h>#include <plasma/theme.h>#include <Plasma/Separator>#include <KRichTextWidget>#include "entrywidget.h"#include "khluurrooster.h"KHLUurrooster::KHLUurrooster(QObject *parent, const QVariantList &args)    : Plasma::Applet(parent, args){    // this will get us the standard applet background, for free!    setHasConfigurationInterface(true);    setBackgroundHints(DefaultBackground);    resize(300, 200);        //setup the rooster object    rooster = new Uurrooster();    connect(rooster, SIGNAL(errorOccurred(QString)), this, SLOT(roosterError(QString)));    connect(rooster, SIGNAL(entriesChanged()), this, SLOT(sendNextIcalLink()));        //set the timer who get the latest uurrooster information online    timerUpdate = new QTimer(this);    connect(timerUpdate, SIGNAL(timeout()), this, SLOT(updateRoosters()));        //set the refresh timer    timerRefresh = new QTimer(this);    timerRefresh->start(60 * 1000); //om de minuut de entries hertekenen    connect(timerRefresh, SIGNAL(timeout()), this, SLOT(displayEntries()));        //set the error timer    timerError = new QTimer(this);    connect(timerError, SIGNAL(timeout()), this, SLOT(updateRoosters()));            //make layout for the widget    layout = new QGraphicsGridLayout(this);    setLayout(layout);        //set date    date = QDate::currentDate();        //set UI components    headerLabel = new Plasma::Label();    vorigeButton = new Plasma::PushButton();    volgendeButton = new Plasma::PushButton();    m_scrollWidget = new Plasma::ScrollWidget();    m_scroller = new QGraphicsWidget();    m_scrollerLayout = new QGraphicsLinearLayout(Qt::Vertical, m_scroller);        //configre the UI components    headerLabel->setAlignment(Qt::AlignCenter);    m_scrollWidget->setMinimumSize(300, 200);    m_scrollWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);     m_scrollWidget->setWidget(m_scroller);        //connect the buttons    connect(vorigeButton, SIGNAL(clicked()), this, SLOT(prevDate()));    connect(volgendeButton, SIGNAL(clicked()), this, SLOT(nextDate()));        //add to layout    layout->addItem(headerLabel, 0, 0, 1, 2);    layout->addItem(m_scrollWidget, 1, 0, 1, 2);    layout->addItem(vorigeButton, 2, 0);    layout->addItem(volgendeButton, 2, 1);}KHLUurrooster::~KHLUurrooster(){}void KHLUurrooster::init(){    readConfig();        //make ~/.khl_personal.xml    file = new QFile(QDir::homePath() + "/.khl_personal.xml");    if(! file->exists()) {      QDomDocument doc("personal");      QDomElement root = doc.createElement("entries");      doc.appendChild(root);      file->open(QIODevice::WriteOnly);      file->write(doc.toByteArray());      file->close();    }        if(ical_1.isEmpty() && ical_2.isEmpty() && ical_3.isEmpty()) { //no configuration setted yet      this->setConfigurationRequired(true, "Je moet op zijn minst 1 iCal link opgeven");    } else {      configChanged();    }}void KHLUurrooster::showHelp(){    KDialog *dialog = new KDialog();    dialog->setCaption("Help pagina");    dialog->setButtons(KDialog::Ok);        KRichTextWidget *widget = new KRichTextWidget(dialog);    widget->setHtml("<h1>KHL Uurrooster KDE widget</h1><ul><li><a href=\"#over\">Over de widget</a></li><li><a href=\"#configuratie\">Configuratie</a></li><li><a href=\"#personal\">Zelf afspraken toevoegen</a></li></ul><a name=\"over\" /><h2>Over de widget</h2><p>De KHL Uurrooster KDE widget is een KDE widget. Een KDE widget is een programma dat draait op je bureaublad. De bedoeling van deze widget is om het uurrooster van de student te tonen. Omdat er op iedere uurrooster pagia van de KHL een iCal link is voorzien, werkt deze widget met die iCal kalender.</p><p>De widget laat de verschillende uurroosters zien in verschillende kleuren en kan ook zelfde vakken verbergen. Stel dat je les volgt in verschillende reeksen, dan kan het zijn dat die reeksen gemeenschappelijke vakken heeft, die kan je laten verbergen.</p><p>Je kan ook zelf afspraken toevoegen. Dit kan handig zijn om je uurrooster een persoonlijke touch te geven. Zo kan je afspraken met lectoren erbij plaatsen.</p><p>Deze widget is gemaakt door Stijn Leenknegt, student aan de KHL departement G&amp;T, voor het vak Small ICT Projects. De widget kan je ook vinden op de volgende website: <a href=\"http://aiids.wordpress.com/khl-uurrooster-applet/\">http://aiids.wordpress.com/khl-uurrooster-applet/</<a>.</p><a name=\"configuratie\" /><h2>Configuratie</h2><p>Bij de configuratie heb je drie tabs: iCal instellingen, Opties en Afspraak toevoegen. De eerste tab is belangrijk. Wanneer je op de portaal site bent en je gaat naar je uurrooster zie je op de pagina de tekst <em>ICal-adres voor deze uurrooster</em> staan. De link moet je kopieren en plakken in een veldje. Je begint bij <em>iCal link 1</em> en gaat zo verder tot <em>iCal link 3</em>. Je kan dus drie uurroosters toevoegen indien je les volgt in meerdere reeksen.</p><p>Bij het tablblad <em>Opties</em> kan je de kleuren instellen en ook kiezen of je dubbele vakken wilt verbergen.</p><a name=\"personal\" /><h2>Zelf afspraken toevoegen</h2>Je kan ook zelf afspraken toevoegen. Bij de configuratie klik je op het derde tabblad en vul je de gegevens in. Wanneer je op toevoegen klikt, wordt alles toevoegd aan een XML bestand <em>(~/.khl_personal.xml)</em> en getoond in je uurrooster widget.</p>");        dialog->setMainWidget(widget);    dialog->setGeometry(0, 0, 600, 450);    dialog->show();}void KHLUurrooster::createConfigurationInterface(KConfigDialog *parent){    QWidget *widget = new QWidget(0);    ui.setupUi(widget);        //als er op ok of apply gedrukt is, moet de config opgeslaan worden    connect(parent, SIGNAL(okClicked()), this, SLOT(configAccepted()));    connect(parent, SIGNAL(applyClicked()), this, SLOT(configAccepted()));    connect(parent, SIGNAL(user1Clicked()), this, SLOT(showHelp()));        //stel de value van de textbox in    ui.txtIcal_1->setText(ical_1);    ui.txtIcal_2->setText(ical_2);    ui.txtIcal_3->setText(ical_3);        //stel de opties in    ui.checkDuplicates->setChecked(hide_duplicates);    if(! ical_1_color.isEmpty()) {      ui.comboKleur1->setCurrentIndex(ui.comboKleur1->findText(ical_1_color));    }    if(! ical_2_color.isEmpty()) {      ui.comboKleur2->setCurrentIndex(ui.comboKleur1->findText(ical_2_color));    }    if(! ical_3_color.isEmpty()) {      ui.comboKleur3->setCurrentIndex(ui.comboKleur1->findText(ical_3_color));    }    if(! personal_color.isEmpty()) {      ui.comboKleurA->setCurrentIndex(ui.comboKleur1->findText(personal_color));    }        //personal entries toevoegen    ui.dtStart->setDateTime(QDateTime::currentDateTime());    ui.dtEind->setDateTime(QDateTime::currentDateTime().addSecs(3600));    connect(ui.btnToevoegen, SIGNAL(clicked(bool)), this, SLOT(savePersonalEntry()));        //alle persoonlijke entries toevoegen aan de delete lijst    QList<uurrooster_entry> *p_entries = rooster->getPersonalEntries();    for(int i = 0 ; i < p_entries->size() ; i++) {      ui.comboDelete->addItem(p_entries->at(i).beschrijving);    }    connect(ui.btnDelete, SIGNAL(clicked(bool)), this, SLOT(deletePersonalEntry()));    parent->setButtons(KDialog::Ok | KDialog::Apply | KDialog::Cancel | KDialog::User1);    parent->setButtonIcon(KDialog::User1, KIcon("help-contents"));    parent->setButtonText(KDialog::User1, "Help");    parent->setGeometry(QRect(0, 0, 475, 350));    parent->addPage(widget, "KHL Uurrooster", "view-calendar-list");}void KHLUurrooster::readConfig(){    KConfigGroup cg = config();    ical_1 = cg.readEntry("ical_1");    ical_2 = cg.readEntry("ical_2");    ical_3 = cg.readEntry("ical_3");    ical_1_color = cg.readEntry("ical_1_color");    ical_2_color = cg.readEntry("ical_2_color");    ical_3_color = cg.readEntry("ical_3_color");    personal_color = cg.readEntry("personal_color");    hide_duplicates = (cg.readEntry("hide_duplicates") == "true") ? true : false;}void KHLUurrooster::configChanged(){    //stop the timers    if(timerUpdate->isActive()) timerUpdate->stop();    if(timerRefresh->isActive()) timerRefresh->stop();    if(timerError->isActive()) timerError->stop();        //get the config    readConfig();        //check if filled in    if(ical_1.isEmpty() && ical_2.isEmpty() && ical_3.isEmpty()) { //no configuration setted yet      this->setConfigurationRequired(true, "Je moet op zijn minst 1 iCal link opgeven");    } else {      this->setConfigurationRequired(false, "Je moet op zijn minst 1 iCal link opgeven");      //update het uurrooster, hier wordt het ical terug opgehaald.      ical_busy = 1;      rooster->removeEntries();      rooster->update(ical_1, ical_1_color, hide_duplicates);            //start the timer with a given timeout, default it's once a hour. It checks if the uurrooster is updated online or not.      timerUpdate->start(60 * 60 * 1000);    }}void KHLUurrooster::configAccepted(){    ical_1 = ui.txtIcal_1->text();    ical_2 = ui.txtIcal_2->text();    ical_3 = ui.txtIcal_3->text();    ical_1_color = ui.comboKleur1->currentText();    ical_2_color = ui.comboKleur2->currentText();    ical_3_color = ui.comboKleur3->currentText();    personal_color = ui.comboKleurA->currentText();    hide_duplicates = ui.checkDuplicates->isChecked();        KConfigGroup cg = config();    cg.writeEntry("ical_1", ical_1);    cg.writeEntry("ical_2", ical_2);    cg.writeEntry("ical_3", ical_3);    cg.writeEntry("ical_1_color", ical_1_color);    cg.writeEntry("ical_2_color", ical_2_color);    cg.writeEntry("ical_3_color", ical_3_color);    cg.writeEntry("personal_color", personal_color);    cg.writeEntry("hide_duplicates", (hide_duplicates) ? "true" : "false");        emit configNeedsSaving();}void KHLUurrooster::paintInterface(QPainter *p, const QStyleOptionGraphicsItem *option, const QRect &contentsRect){    Q_UNUSED(option);    p->setRenderHint(QPainter::SmoothPixmapTransform);    p->setRenderHint(QPainter::Antialiasing);    layout->setGeometry(contentsRect);}void KHLUurrooster::displayEntries(){    if(ical_1.isEmpty() && ical_2.isEmpty() && ical_3.isEmpty()) return;        //ff de refreshtimer stoppen    if(timerRefresh->isActive()) {      timerRefresh->stop();    }        //de uurrooster entries, mooi gesorteerd.    QList<uurrooster_entry>  *entries= rooster->getEntries(date);        //delete body frame entries    QGraphicsLayoutItem *item;    while(m_scrollerLayout->count() > 0) {      item = m_scrollerLayout->itemAt(m_scrollerLayout->count() - 1);      m_scrollerLayout->removeItem(item);      delete item;    }        //set the label text    headerLabel->setText("<b>" + date.toString(Qt::DefaultLocaleLongDate) + "</b>");        //set the button labels    vorigeButton->setText(date.addDays(-1).toString());    volgendeButton->setText(date.addDays(1).toString());        //add entries to frame    if(entries->count() > 0) {      EntryWidget *widget;      Plasma::Separator *sep;      QTime currTime = QTime::currentTime();      QDate currDate = QDate::currentDate();            //loop the entries      for(int i = 0 ; i < entries->size() ; i++) {        //markeer de items die nu bezig zijn in het bold        if(entries->at(i).starttijd.date() == currDate && entries->at(i).starttijd.time() <= currTime && currTime <= entries->at(i).eindtijd.time()) {          widget = new EntryWidget(entries->at(i), true);        } else {          widget = new EntryWidget(entries->at(i), false);        }        m_scrollerLayout->addItem(widget);                //scheiding toevoegen tussen de verschillende entries        if(i != entries->size()-1) {          sep = new Plasma::Separator();          sep->setOrientation(Qt::Horizontal);          m_scrollerLayout->addItem(sep);        }      }    } else {      Plasma::Label *nothingLabel;      nothingLabel = new Plasma::Label();      nothingLabel->setText("Geen les vandaag! JOEPIE!");      nothingLabel->setAlignment(Qt::AlignCenter);      m_scroller->resize(300, 200);      m_scrollerLayout->addItem(nothingLabel);    }        //resume the refresh timer    timerRefresh->start(60 * 1000);}void KHLUurrooster::displayError(const QString& error){    //stop de timers    if(timerUpdate->isActive()) timerUpdate->stop();    if(timerRefresh->isActive()) timerRefresh->stop();    if(timerError->isActive()) timerError->stop();        //delete body frame entries    QGraphicsLayoutItem *item;    while(m_scrollerLayout->count() > 0) {      item = m_scrollerLayout->itemAt(m_scrollerLayout->count() - 1);      m_scrollerLayout->removeItem(item);      delete item;    }        //display the error on applet    Plasma::Label *errorLabel = new Plasma::Label();    errorLabel->setText("<b>Fout:</b><br />" + error);    m_scroller->resize(300, 200);    m_scrollerLayout->addItem(errorLabel);        //start error timer met een interval van 10 seconden    timerError->start(10 * 1000);}void KHLUurrooster::updateRoosters(){    if(timerError->isActive()) {      timerError->stop();    }        date = QDate::currentDate();    ical_busy = 1;    rooster->removeEntries();    rooster->update(ical_1, ical_1_color, hide_duplicates);}void KHLUurrooster::roosterError(const QString& error){    displayError(error);}void KHLUurrooster::sendNextIcalLink(){    ical_busy += 1;    if(ical_busy == 2) {      rooster->update(ical_2, ical_2_color, hide_duplicates);    } else if(ical_busy == 3) {      rooster->update(ical_3, ical_3_color, hide_duplicates);    } else {      rooster->updatePersonal(personal_color);      displayEntries();    }}void KHLUurrooster::nextDate(){    if(! timerError->isActive()) {      date = date.addDays(1);      displayEntries();    }}void KHLUurrooster::prevDate(){    if(! timerError->isActive()) {      date = date.addDays(-1);      displayEntries();    }}void KHLUurrooster::savePersonalEntry(){  QDomDocument *doc = new QDomDocument("personal");  if(file != NULL) delete file;  file = new QFile(QDir::homePath() + "/.khl_personal.xml");    file->open(QIODevice::ReadWrite);  doc->setContent(file);    //find root  QDomElement root = doc->documentElement();    //maak een element  QDomElement entry = doc->createElement("entry");  QDomElement beschrijving = doc->createElement("beschrijving");  QDomElement locatie = doc->createElement("locatie");  QDomElement starttijd = doc->createElement("starttijd");  QDomElement eindtijd = doc->createElement("eindtijd");    //maak de content elementen  QDomText txtBeschrijving = doc->createTextNode(ui.txtOmschrijving->text());  QDomText txtLocatie = doc->createTextNode(ui.txtLocatie->text());  QDomText txtStarttijd = doc->createTextNode(ui.dtStart->text());  QDomText txtEindtijd = doc->createTextNode(ui.dtEind->text());    //link elements met inhoud  beschrijving.appendChild(txtBeschrijving);  locatie.appendChild(txtLocatie);  starttijd.appendChild(txtStarttijd);  eindtijd.appendChild(txtEindtijd);    //link elementen met de entry elementen  entry.appendChild(beschrijving);  entry.appendChild(locatie);  entry.appendChild(starttijd);  entry.appendChild(eindtijd);    //append it to the xml  root.appendChild(entry);    //write it to the file  file->resize(0);  file->write(doc->toByteArray());  file->close();    //show message   ui.comboDelete->addItem(ui.txtOmschrijving->text());  ui.txtLocatie->setText("");  ui.txtOmschrijving->setText("");  ui.dtStart->setDateTime(QDateTime::currentDateTime());  ui.dtEind->setDateTime(QDateTime::currentDateTime().addSecs(3600));  KMessageBox::information(NULL, "Afspraak toegevoegd!");}void KHLUurrooster::deletePersonalEntry(){  QString beschrijving = ui.comboDelete->currentText();  QDomDocument *doc = new QDomDocument("personal");  QFile *file = new QFile(QDir::homePath() + "/.khl_personal.xml");    file->open(QIODevice::ReadWrite);  doc->setContent(file);    //find root  QDomElement root = doc->documentElement();    //iterate the personal elements  QDomNodeList nodeList = root.elementsByTagName("entry");  QDomNode el;  for(int i = 0 ; i < nodeList.size() ; i++) {    el = nodeList.at(i);    if(el.childNodes().at(0).childNodes().at(0).nodeValue() == beschrijving) {      root.removeChild(el);    }  }    file->resize(0);  file->write(doc->toByteArray());  file->close();  ui.comboDelete->removeItem(ui.comboDelete->currentIndex());  KMessageBox::information(NULL, "Afspraak verwijderd!");  updateRoosters();}#include "khluurrooster.moc"