Back to index

fet  5.18.0
addconstraintactivitiesmaxsimultaneousinselectedtimeslotsform.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                           addconstraintactivitiesmaxsimultaneousinselectedtimeslotsform.cpp  -  description
00003                              -------------------
00004     begin                : Sept 26, 2011
00005     copyright            : (C) 2011 by Lalescu Liviu
00006     email                : Please see http://lalescu.ro/liviu/ for details about contacting Liviu Lalescu (in particular, you can find here the e-mail address)
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00018 #include <QMessageBox>
00019 
00020 #include "tablewidgetupdatebug.h"
00021 
00022 #include "longtextmessagebox.h"
00023 
00024 #include "addconstraintactivitiesmaxsimultaneousinselectedtimeslotsform.h"
00025 #include "timeconstraint.h"
00026 
00027 #include <QHeaderView>
00028 #include <QTableWidget>
00029 #include <QTableWidgetItem>
00030 
00031 #include <QListWidget>
00032 #include <QAbstractItemView>
00033 #include <QScrollBar>
00034 
00035 #include <QBrush>
00036 #include <QColor>
00037 
00038 #define YES   (QString("X"))
00039 #define NO    (QString(" "))
00040 
00041 AddConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::AddConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm(QWidget* parent): QDialog(parent)
00042 {
00043        setupUi(this);
00044 
00045        addConstraintPushButton->setDefault(true);
00046        
00047        allActivitiesListWidget->setSelectionMode(QAbstractItemView::SingleSelection);
00048        selectedActivitiesListWidget->setSelectionMode(QAbstractItemView::SingleSelection);
00049        
00050        connect(addConstraintPushButton, SIGNAL(clicked()), this, SLOT(addCurrentConstraint()));
00051        connect(closePushButton, SIGNAL(clicked()), this, SLOT(close()));
00052        connect(selectedTimesTable, SIGNAL(itemClicked(QTableWidgetItem*)), this, SLOT(itemClicked(QTableWidgetItem*)));
00053        connect(setAllUnselectedPushButton, SIGNAL(clicked()), this, SLOT(setAllUnselected()));
00054        connect(setAllSelectedPushButton, SIGNAL(clicked()), this, SLOT(setAllSelected()));
00055        connect(allActivitiesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(addActivity()));
00056        connect(addAllActivitiesPushButton, SIGNAL(clicked()), this, SLOT(addAllActivities()));
00057        connect(selectedActivitiesListWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(removeActivity()));
00058        connect(clearPushButton, SIGNAL(clicked()), this, SLOT(clear()));
00059        connect(teachersComboBox, SIGNAL(activated(QString)), this, SLOT(filterChanged()));
00060        connect(studentsComboBox, SIGNAL(activated(QString)), this, SLOT(filterChanged()));
00061        connect(subjectsComboBox, SIGNAL(activated(QString)), this, SLOT(filterChanged()));
00062        connect(activityTagsComboBox, SIGNAL(activated(QString)), this, SLOT(filterChanged()));
00063        
00064        centerWidgetOnScreen(this);
00065        restoreFETDialogGeometry(this);
00066                                                  
00067        tabWidget->setCurrentIndex(0);
00068 
00069        maxSimultaneousSpinBox->setMinimum(0);
00070        maxSimultaneousSpinBox->setMaximum(MAX_ACTIVITIES);
00071        maxSimultaneousSpinBox->setValue(0);
00072 
00073        selectedTimesTable->setRowCount(gt.rules.nHoursPerDay);
00074        selectedTimesTable->setColumnCount(gt.rules.nDaysPerWeek);
00075 
00076        for(int j=0; j<gt.rules.nDaysPerWeek; j++){
00077               QTableWidgetItem* item=new QTableWidgetItem(gt.rules.daysOfTheWeek[j]);
00078               selectedTimesTable->setHorizontalHeaderItem(j, item);
00079        }
00080        for(int i=0; i<gt.rules.nHoursPerDay; i++){
00081               QTableWidgetItem* item=new QTableWidgetItem(gt.rules.hoursOfTheDay[i]);
00082               selectedTimesTable->setVerticalHeaderItem(i, item);
00083        }
00084 
00085        for(int i=0; i<gt.rules.nHoursPerDay; i++)
00086               for(int j=0; j<gt.rules.nDaysPerWeek; j++){
00087                      QTableWidgetItem* item=new QTableWidgetItem(NO);
00088                      item->setTextAlignment(Qt::AlignCenter);
00089                      item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
00090                      colorItem(item);
00091                      selectedTimesTable->setItem(i, j, item);
00092               }
00093               
00094        selectedTimesTable->resizeRowsToContents();
00095        //selectedTimesTable->resizeColumnsToContents();
00096 
00097        connect(selectedTimesTable->horizontalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(horizontalHeaderClicked(int)));
00098        connect(selectedTimesTable->verticalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(verticalHeaderClicked(int)));
00099 
00100        selectedTimesTable->setSelectionMode(QAbstractItemView::NoSelection);
00101        
00102        tableWidgetUpdateBug(selectedTimesTable);
00103        
00104        setStretchAvailabilityTableNicely(selectedTimesTable);
00105        
00106        //activities
00107        QSize tmp1=teachersComboBox->minimumSizeHint();
00108        Q_UNUSED(tmp1);
00109        QSize tmp2=studentsComboBox->minimumSizeHint();
00110        Q_UNUSED(tmp2);
00111        QSize tmp3=subjectsComboBox->minimumSizeHint();
00112        Q_UNUSED(tmp3);
00113        QSize tmp4=activityTagsComboBox->minimumSizeHint();
00114        Q_UNUSED(tmp4);
00115 
00116        teachersComboBox->addItem("");
00117        for(int i=0; i<gt.rules.teachersList.size(); i++){
00118               Teacher* tch=gt.rules.teachersList[i];
00119               teachersComboBox->addItem(tch->name);
00120        }
00121        teachersComboBox->setCurrentIndex(0);
00122 
00123        subjectsComboBox->addItem("");
00124        for(int i=0; i<gt.rules.subjectsList.size(); i++){
00125               Subject* sb=gt.rules.subjectsList[i];
00126               subjectsComboBox->addItem(sb->name);
00127        }
00128        subjectsComboBox->setCurrentIndex(0);
00129 
00130        activityTagsComboBox->addItem("");
00131        for(int i=0; i<gt.rules.activityTagsList.size(); i++){
00132               ActivityTag* st=gt.rules.activityTagsList[i];
00133               activityTagsComboBox->addItem(st->name);
00134        }
00135        activityTagsComboBox->setCurrentIndex(0);
00136 
00137        studentsComboBox->addItem("");
00138        for(int i=0; i<gt.rules.yearsList.size(); i++){
00139               StudentsYear* sty=gt.rules.yearsList[i];
00140               studentsComboBox->addItem(sty->name);
00141               for(int j=0; j<sty->groupsList.size(); j++){
00142                      StudentsGroup* stg=sty->groupsList[j];
00143                      studentsComboBox->addItem(stg->name);
00144                      for(int k=0; k<stg->subgroupsList.size(); k++){
00145                             StudentsSubgroup* sts=stg->subgroupsList[k];
00146                             studentsComboBox->addItem(sts->name);
00147                      }
00148               }
00149        }
00150        studentsComboBox->setCurrentIndex(0);
00151 
00152        selectedActivitiesListWidget->clear();
00153        selectedActivitiesList.clear();
00154 
00155        filterChanged();
00156 }
00157 
00158 AddConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::~AddConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm()
00159 {
00160        saveFETDialogGeometry(this);
00161 }
00162 
00163 void AddConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::colorItem(QTableWidgetItem* item)
00164 {
00165        if(USE_GUI_COLORS){
00166               if(item->text()==NO)
00167                      item->setBackground(QBrush(Qt::darkGreen));
00168               else
00169                      item->setBackground(QBrush(Qt::darkRed));
00170               item->setForeground(QBrush(Qt::lightGray));
00171        }
00172 }
00173 
00174 void AddConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::horizontalHeaderClicked(int col)
00175 {
00176        if(col>=0 && col<gt.rules.nDaysPerWeek){
00177               QString s=selectedTimesTable->item(0, col)->text();
00178               if(s==YES)
00179                      s=NO;
00180               else{
00181                      assert(s==NO);
00182                      s=YES;
00183               }
00184 
00185               for(int row=0; row<gt.rules.nHoursPerDay; row++){
00186                      selectedTimesTable->item(row, col)->setText(s);
00187                      colorItem(selectedTimesTable->item(row,col));
00188               }
00189               tableWidgetUpdateBug(selectedTimesTable);
00190        }
00191 }
00192 
00193 void AddConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::verticalHeaderClicked(int row)
00194 {
00195        if(row>=0 && row<gt.rules.nHoursPerDay){
00196               QString s=selectedTimesTable->item(row, 0)->text();
00197               if(s==YES)
00198                      s=NO;
00199               else{
00200                      assert(s==NO);
00201                      s=YES;
00202               }
00203        
00204               for(int col=0; col<gt.rules.nDaysPerWeek; col++){
00205                      selectedTimesTable->item(row, col)->setText(s);
00206                      colorItem(selectedTimesTable->item(row,col));
00207               }
00208               tableWidgetUpdateBug(selectedTimesTable);
00209        }
00210 }
00211 
00212 void AddConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::setAllUnselected()
00213 {
00214        for(int i=0; i<gt.rules.nHoursPerDay; i++)
00215               for(int j=0; j<gt.rules.nDaysPerWeek; j++){
00216                      selectedTimesTable->item(i, j)->setText(NO);
00217                      colorItem(selectedTimesTable->item(i,j));
00218               }
00219        tableWidgetUpdateBug(selectedTimesTable);
00220 }
00221 
00222 void AddConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::setAllSelected()
00223 {
00224        for(int i=0; i<gt.rules.nHoursPerDay; i++)
00225               for(int j=0; j<gt.rules.nDaysPerWeek; j++){
00226                      selectedTimesTable->item(i, j)->setText(YES);
00227                      colorItem(selectedTimesTable->item(i,j));
00228               }
00229        tableWidgetUpdateBug(selectedTimesTable);
00230 }
00231 
00232 void AddConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::itemClicked(QTableWidgetItem* item)
00233 {
00234        QString s=item->text();
00235        if(s==YES)
00236               s=NO;
00237        else{
00238               assert(s==NO);
00239               s=YES;
00240        }
00241        item->setText(s);
00242        colorItem(item);
00243        
00244        tableWidgetUpdateBug(selectedTimesTable);
00245 }
00246 
00247 void AddConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::addCurrentConstraint()
00248 {
00249        TimeConstraint *ctr=NULL;
00250 
00251        double weight;
00252        QString tmp=weightLineEdit->text();
00253        weight_sscanf(tmp, "%lf", &weight);
00254        if(weight<100.0 || weight>100.0){
00255               QMessageBox::warning(this, tr("FET information"),
00256                      tr("Invalid weight (percentage). It has to be 100"));
00257               return;
00258        }
00259 
00260        QList<int> days;
00261        QList<int> hours;
00262        for(int j=0; j<gt.rules.nDaysPerWeek; j++)
00263               for(int i=0; i<gt.rules.nHoursPerDay; i++)
00264                      if(selectedTimesTable->item(i, j)->text()==YES){
00265                             days.append(j);
00266                             hours.append(i);
00267                      }
00268                      
00269        int maxSimultaneous=maxSimultaneousSpinBox->value();
00270        
00271        if(maxSimultaneous==0){
00272               QMessageBox::warning(this, tr("FET information"), tr("You specified max simultaneous activities to be 0. This is "
00273                "not perfect from efficiency point of view, because you can use instead constraint activity(ies) preferred time slots, "
00274                "and help FET to find a timetable easier and faster, with an equivalent result. Please correct."));
00275               return;
00276        }
00277        
00278        if(this->selectedActivitiesList.count()==0){
00279               QMessageBox::warning(this, tr("FET information"),
00280                tr("Empty list of activities"));
00281               return;
00282        }
00283        //we allow even only one activity
00284        /*if(this->selectedActivitiesList.count()==1){
00285               QMessageBox::warning(this, tr("FET information"),
00286                tr("Only one selected activity"));
00287               return;
00288        }*/
00289 
00290        ctr=new ConstraintActivitiesMaxSimultaneousInSelectedTimeSlots(weight, selectedActivitiesList, days, hours, maxSimultaneous);
00291 
00292        bool tmp2=gt.rules.addTimeConstraint(ctr);
00293        if(tmp2)
00294               LongTextMessageBox::information(this, tr("FET information"),
00295                      tr("Constraint added:")+"\n\n"+ctr->getDetailedDescription(gt.rules));
00296        else{
00297               QMessageBox::warning(this, tr("FET information"),
00298                      tr("Constraint NOT added - please report error"));
00299               delete ctr;
00300        }
00301 }
00302 
00303 //activities
00304 bool AddConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::filterOk(Activity* act)
00305 {
00306        QString tn=teachersComboBox->currentText();
00307        QString stn=studentsComboBox->currentText();
00308        QString sbn=subjectsComboBox->currentText();
00309        QString sbtn=activityTagsComboBox->currentText();
00310        int ok=true;
00311 
00312        //teacher
00313        if(tn!=""){
00314               bool ok2=false;
00315               for(QStringList::Iterator it=act->teachersNames.begin(); it!=act->teachersNames.end(); it++)
00316                      if(*it == tn){
00317                             ok2=true;
00318                             break;
00319                      }
00320               if(!ok2)
00321                      ok=false;
00322        }
00323 
00324        //subject
00325        if(sbn!="" && sbn!=act->subjectName)
00326               ok=false;
00327               
00328        //activity tag
00329        if(sbtn!="" && !act->activityTagsNames.contains(sbtn))
00330               ok=false;
00331               
00332        //students
00333        if(stn!=""){
00334               bool ok2=false;
00335               for(QStringList::Iterator it=act->studentsNames.begin(); it!=act->studentsNames.end(); it++)
00336                      if(*it == stn){
00337                             ok2=true;
00338                             break;
00339                      }
00340               if(!ok2)
00341                      ok=false;
00342        }
00343        
00344        return ok;
00345 }
00346 
00347 void AddConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::filterChanged()
00348 {
00349        this->updateActivitiesListWidget();
00350 }
00351 
00352 void AddConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::updateActivitiesListWidget()
00353 {
00354        allActivitiesListWidget->clear();
00355        this->activitiesList.clear();
00356        
00357        for(int i=0; i<gt.rules.activitiesList.size(); i++){
00358               Activity* ac=gt.rules.activitiesList[i];
00359               if(filterOk(ac)){
00360                      allActivitiesListWidget->addItem(ac->getDescription(gt.rules));
00361                      this->activitiesList.append(ac->id);
00362               }
00363        }
00364        
00365        int q=allActivitiesListWidget->verticalScrollBar()->minimum();
00366        allActivitiesListWidget->verticalScrollBar()->setValue(q);
00367 }
00368 
00369 void AddConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::addActivity()
00370 {
00371        if(allActivitiesListWidget->currentRow()<0)
00372               return;
00373        int tmp=allActivitiesListWidget->currentRow();
00374        int _id=this->activitiesList.at(tmp);
00375        
00376        QString actName=allActivitiesListWidget->currentItem()->text();
00377        assert(actName!="");
00378        int i;
00379        //duplicate?
00380        for(i=0; i<selectedActivitiesListWidget->count(); i++)
00381               if(actName==selectedActivitiesListWidget->item(i)->text())
00382                      break;
00383        if(i<selectedActivitiesListWidget->count())
00384               return;
00385        selectedActivitiesListWidget->addItem(actName);
00386        selectedActivitiesListWidget->setCurrentRow(selectedActivitiesListWidget->count()-1);
00387        
00388        this->selectedActivitiesList.append(_id);
00389 }
00390 
00391 void AddConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::addAllActivities()
00392 {
00393        for(int tmp=0; tmp<allActivitiesListWidget->count(); tmp++){
00394               //int tmp=allActivitiesListWidget->currentRow();
00395               int _id=this->activitiesList.at(tmp);
00396        
00397               QString actName=allActivitiesListWidget->item(tmp)->text();
00398               assert(actName!="");
00399               int i;
00400               //duplicate?
00401               for(i=0; i<selectedActivitiesList.count(); i++)
00402                      if(selectedActivitiesList.at(i)==_id)
00403                             break;
00404               if(i<selectedActivitiesList.count())
00405                      continue;
00406               
00407               /*for(i=0; i<selectedActivitiesListWidget->count(); i++)
00408                      if(actName==selectedActivitiesListWidget->item(i)->text())
00409                             break;
00410               if(i<selectedActivitiesListWidget->count())
00411                      continue;*/
00412                      
00413               selectedActivitiesListWidget->addItem(actName);
00414               this->selectedActivitiesList.append(_id);
00415        }
00416        
00417        selectedActivitiesListWidget->setCurrentRow(selectedActivitiesListWidget->count()-1);
00418 }
00419 
00420 void AddConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::removeActivity()
00421 {
00422        if(selectedActivitiesListWidget->currentRow()<0 || selectedActivitiesListWidget->count()<=0)
00423               return;
00424        int tmp=selectedActivitiesListWidget->currentRow();
00425        
00426        selectedActivitiesList.removeAt(tmp);
00427 
00428        selectedActivitiesListWidget->setCurrentRow(-1);
00429        QListWidgetItem* item=selectedActivitiesListWidget->takeItem(tmp);
00430        delete item;
00431        if(tmp<selectedActivitiesListWidget->count())
00432               selectedActivitiesListWidget->setCurrentRow(tmp);
00433        else
00434               selectedActivitiesListWidget->setCurrentRow(selectedActivitiesListWidget->count()-1);
00435 }
00436 
00437 void AddConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::clear()
00438 {
00439        selectedActivitiesListWidget->clear();
00440        selectedActivitiesList.clear();
00441 }