Back to index

fet  5.18.0
modifyconstraintactivitiesmaxsimultaneousinselectedtimeslotsform.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002                           modifyconstraintactivitiesmaxsimultaneousinselectedtimeslotsform.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 "modifyconstraintactivitiesmaxsimultaneousinselectedtimeslotsform.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 ModifyConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::ModifyConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm(QWidget* parent, ConstraintActivitiesMaxSimultaneousInSelectedTimeSlots* ctr): QDialog(parent)
00042 {
00043        setupUi(this);
00044 
00045        okPushButton->setDefault(true);
00046        
00047        allActivitiesListWidget->setSelectionMode(QAbstractItemView::SingleSelection);
00048        selectedActivitiesListWidget->setSelectionMode(QAbstractItemView::SingleSelection);
00049        
00050        connect(okPushButton, SIGNAL(clicked()), this, SLOT(ok()));
00051        connect(cancelPushButton, SIGNAL(clicked()), this, SLOT(cancel()));
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        this->_ctr=ctr;
00068        
00069        weightLineEdit->setText(CustomFETString::number(ctr->weightPercentage));
00070        
00071        tabWidget->setCurrentIndex(0);
00072 
00073        maxSimultaneousSpinBox->setMinimum(0);
00074        maxSimultaneousSpinBox->setMaximum(MAX_ACTIVITIES);
00075        maxSimultaneousSpinBox->setValue(ctr->maxSimultaneous);
00076 
00077        selectedTimesTable->setRowCount(gt.rules.nHoursPerDay);
00078        selectedTimesTable->setColumnCount(gt.rules.nDaysPerWeek);
00079 
00080        for(int j=0; j<gt.rules.nDaysPerWeek; j++){
00081               QTableWidgetItem* item=new QTableWidgetItem(gt.rules.daysOfTheWeek[j]);
00082               selectedTimesTable->setHorizontalHeaderItem(j, item);
00083        }
00084        for(int i=0; i<gt.rules.nHoursPerDay; i++){
00085               QTableWidgetItem* item=new QTableWidgetItem(gt.rules.hoursOfTheDay[i]);
00086               selectedTimesTable->setVerticalHeaderItem(i, item);
00087        }
00088 
00089        for(int i=0; i<gt.rules.nHoursPerDay; i++)
00090               for(int j=0; j<gt.rules.nDaysPerWeek; j++){
00091                      QTableWidgetItem* item=new QTableWidgetItem(NO);
00092                      item->setTextAlignment(Qt::AlignCenter);
00093                      item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
00094                      colorItem(item);
00095                      selectedTimesTable->setItem(i, j, item);
00096               }
00097               
00098        //bool currentMatrix[MAX_HOURS_PER_DAY][MAX_DAYS_PER_WEEK];
00099        Matrix2D<bool> currentMatrix;
00100        currentMatrix.resize(gt.rules.nHoursPerDay, gt.rules.nDaysPerWeek);
00101 
00102        for(int i=0; i<gt.rules.nHoursPerDay; i++)
00103               for(int j=0; j<gt.rules.nDaysPerWeek; j++)
00104                      currentMatrix[i][j]=false;
00105        assert(ctr->selectedDays.count()==ctr->selectedHours.count());
00106        for(int k=0; k<ctr->selectedDays.count(); k++){
00107               if(ctr->selectedHours.at(k)==-1 || ctr->selectedDays.at(k)==-1)
00108                      assert(0);
00109               int i=ctr->selectedHours.at(k);
00110               int j=ctr->selectedDays.at(k);
00111               if(i>=0 && i<gt.rules.nHoursPerDay && j>=0 && j<gt.rules.nDaysPerWeek)
00112                      currentMatrix[i][j]=true;
00113        }
00114 
00115        for(int i=0; i<gt.rules.nHoursPerDay; i++)
00116               for(int j=0; j<gt.rules.nDaysPerWeek; j++){
00117                      QTableWidgetItem* item = new QTableWidgetItem();
00118                      item->setTextAlignment(Qt::AlignCenter);
00119                      item->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
00120                      selectedTimesTable->setItem(i, j, item);
00121 
00122                      if(!currentMatrix[i][j])
00123                             item->setText(NO);
00124                      else
00125                             item->setText(YES);
00126                             
00127                      colorItem(item);
00128               }
00129 
00130        selectedTimesTable->resizeRowsToContents();
00131 
00132        connect(selectedTimesTable->horizontalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(horizontalHeaderClicked(int)));
00133        connect(selectedTimesTable->verticalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(verticalHeaderClicked(int)));
00134 
00135        selectedTimesTable->setSelectionMode(QAbstractItemView::NoSelection);
00136        
00137        tableWidgetUpdateBug(selectedTimesTable);
00138        
00139        setStretchAvailabilityTableNicely(selectedTimesTable);
00140        
00141        //activities
00142        QSize tmp1=teachersComboBox->minimumSizeHint();
00143        Q_UNUSED(tmp1);
00144        QSize tmp2=studentsComboBox->minimumSizeHint();
00145        Q_UNUSED(tmp2);
00146        QSize tmp3=subjectsComboBox->minimumSizeHint();
00147        Q_UNUSED(tmp3);
00148        QSize tmp4=activityTagsComboBox->minimumSizeHint();
00149        Q_UNUSED(tmp4);
00150        
00151        selectedActivitiesList.clear();
00152        selectedActivitiesListWidget->clear();
00153        for(int i=0; i<ctr->activitiesIds.count(); i++){
00154               int actId=ctr->activitiesIds.at(i);
00155               this->selectedActivitiesList.append(actId);
00156               Activity* act=NULL;
00157               for(int k=0; k<gt.rules.activitiesList.size(); k++){
00158                      act=gt.rules.activitiesList[k];
00159                      if(act->id==actId)
00160                             break;
00161               }
00162               assert(act);
00163               this->selectedActivitiesListWidget->addItem(act->getDescription(gt.rules));
00164        }
00165 
00166        teachersComboBox->addItem("");
00167        for(int i=0; i<gt.rules.teachersList.size(); i++){
00168               Teacher* tch=gt.rules.teachersList[i];
00169               teachersComboBox->addItem(tch->name);
00170        }
00171        teachersComboBox->setCurrentIndex(0);
00172 
00173        subjectsComboBox->addItem("");
00174        for(int i=0; i<gt.rules.subjectsList.size(); i++){
00175               Subject* sb=gt.rules.subjectsList[i];
00176               subjectsComboBox->addItem(sb->name);
00177        }
00178        subjectsComboBox->setCurrentIndex(0);
00179 
00180        activityTagsComboBox->addItem("");
00181        for(int i=0; i<gt.rules.activityTagsList.size(); i++){
00182               ActivityTag* st=gt.rules.activityTagsList[i];
00183               activityTagsComboBox->addItem(st->name);
00184        }
00185        activityTagsComboBox->setCurrentIndex(0);
00186 
00187        studentsComboBox->addItem("");
00188        for(int i=0; i<gt.rules.yearsList.size(); i++){
00189               StudentsYear* sty=gt.rules.yearsList[i];
00190               studentsComboBox->addItem(sty->name);
00191               for(int j=0; j<sty->groupsList.size(); j++){
00192                      StudentsGroup* stg=sty->groupsList[j];
00193                      studentsComboBox->addItem(stg->name);
00194                      for(int k=0; k<stg->subgroupsList.size(); k++){
00195                             StudentsSubgroup* sts=stg->subgroupsList[k];
00196                             studentsComboBox->addItem(sts->name);
00197                      }
00198               }
00199        }
00200        studentsComboBox->setCurrentIndex(0);
00201 
00202        filterChanged();
00203 }
00204 
00205 ModifyConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::~ModifyConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm()
00206 {
00207        saveFETDialogGeometry(this);
00208 }
00209 
00210 void ModifyConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::colorItem(QTableWidgetItem* item)
00211 {
00212        if(USE_GUI_COLORS){
00213               if(item->text()==NO)
00214                      item->setBackground(QBrush(Qt::darkGreen));
00215               else
00216                      item->setBackground(QBrush(Qt::darkRed));
00217               item->setForeground(QBrush(Qt::lightGray));
00218        }
00219 }
00220 
00221 void ModifyConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::horizontalHeaderClicked(int col)
00222 {
00223        if(col>=0 && col<gt.rules.nDaysPerWeek){
00224               QString s=selectedTimesTable->item(0, col)->text();
00225               if(s==YES)
00226                      s=NO;
00227               else{
00228                      assert(s==NO);
00229                      s=YES;
00230               }
00231 
00232               for(int row=0; row<gt.rules.nHoursPerDay; row++){
00233                      selectedTimesTable->item(row, col)->setText(s);
00234                      colorItem(selectedTimesTable->item(row,col));
00235               }
00236               tableWidgetUpdateBug(selectedTimesTable);
00237        }
00238 }
00239 
00240 void ModifyConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::verticalHeaderClicked(int row)
00241 {
00242        if(row>=0 && row<gt.rules.nHoursPerDay){
00243               QString s=selectedTimesTable->item(row, 0)->text();
00244               if(s==YES)
00245                      s=NO;
00246               else{
00247                      assert(s==NO);
00248                      s=YES;
00249               }
00250        
00251               for(int col=0; col<gt.rules.nDaysPerWeek; col++){
00252                      selectedTimesTable->item(row, col)->setText(s);
00253                      colorItem(selectedTimesTable->item(row,col));
00254               }
00255               tableWidgetUpdateBug(selectedTimesTable);
00256        }
00257 }
00258 
00259 void ModifyConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::setAllUnselected()
00260 {
00261        for(int i=0; i<gt.rules.nHoursPerDay; i++)
00262               for(int j=0; j<gt.rules.nDaysPerWeek; j++){
00263                      selectedTimesTable->item(i, j)->setText(NO);
00264                      colorItem(selectedTimesTable->item(i,j));
00265               }
00266        tableWidgetUpdateBug(selectedTimesTable);
00267 }
00268 
00269 void ModifyConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::setAllSelected()
00270 {
00271        for(int i=0; i<gt.rules.nHoursPerDay; i++)
00272               for(int j=0; j<gt.rules.nDaysPerWeek; j++){
00273                      selectedTimesTable->item(i, j)->setText(YES);
00274                      colorItem(selectedTimesTable->item(i,j));
00275               }
00276        tableWidgetUpdateBug(selectedTimesTable);
00277 }
00278 
00279 void ModifyConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::itemClicked(QTableWidgetItem* item)
00280 {
00281        QString s=item->text();
00282        if(s==YES)
00283               s=NO;
00284        else{
00285               assert(s==NO);
00286               s=YES;
00287        }
00288        item->setText(s);
00289        colorItem(item);
00290        
00291        tableWidgetUpdateBug(selectedTimesTable);
00292 }
00293 
00294 void ModifyConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::ok()
00295 {
00296        double weight;
00297        QString tmp=weightLineEdit->text();
00298        weight_sscanf(tmp, "%lf", &weight);
00299        if(weight<100.0 || weight>100.0){
00300               QMessageBox::warning(this, tr("FET information"),
00301                      tr("Invalid weight (percentage). It has to be 100"));
00302               return;
00303        }
00304        
00305        this->_ctr->weightPercentage=weight;
00306 
00307        QList<int> days;
00308        QList<int> hours;
00309        for(int j=0; j<gt.rules.nDaysPerWeek; j++)
00310               for(int i=0; i<gt.rules.nHoursPerDay; i++)
00311                      if(selectedTimesTable->item(i, j)->text()==YES){
00312                             days.append(j);
00313                             hours.append(i);
00314                      }
00315        this->_ctr->selectedDays=days;
00316        this->_ctr->selectedHours=hours;
00317        
00318        int maxSimultaneous=maxSimultaneousSpinBox->value();
00319        
00320        if(maxSimultaneous==0){
00321               QMessageBox::warning(this, tr("FET information"), tr("You specified max simultaneous activities to be 0. This is "
00322                "not perfect from efficiency point of view, because you can use instead constraint activity(ies) preferred time slots, "
00323                "and help FET to find a timetable easier and faster, with an equivalent result. Please correct."));
00324               return;
00325        }
00326        
00327        this->_ctr->maxSimultaneous=maxSimultaneous;
00328 
00329        if(this->selectedActivitiesList.count()==0){
00330               QMessageBox::warning(this, tr("FET information"),
00331                tr("Empty list of activities"));
00332               return;
00333        }
00334        //we allow even only one activity
00335        /*if(this->selectedActivitiesList.count()==1){
00336               QMessageBox::warning(this, tr("FET information"),
00337                tr("Only one selected activity"));
00338               return;
00339        }*/
00340        
00341        this->_ctr->activitiesIds=selectedActivitiesList;
00342        
00343        gt.rules.internalStructureComputed=false;
00344        setRulesModifiedAndOtherThings(&gt.rules);
00345        
00346        this->close();
00347 }
00348 
00349 void ModifyConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::cancel()
00350 {
00351        this->close();
00352 }
00353 
00354 //activities
00355 bool ModifyConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::filterOk(Activity* act)
00356 {
00357        QString tn=teachersComboBox->currentText();
00358        QString stn=studentsComboBox->currentText();
00359        QString sbn=subjectsComboBox->currentText();
00360        QString sbtn=activityTagsComboBox->currentText();
00361        int ok=true;
00362 
00363        //teacher
00364        if(tn!=""){
00365               bool ok2=false;
00366               for(QStringList::Iterator it=act->teachersNames.begin(); it!=act->teachersNames.end(); it++)
00367                      if(*it == tn){
00368                             ok2=true;
00369                             break;
00370                      }
00371               if(!ok2)
00372                      ok=false;
00373        }
00374 
00375        //subject
00376        if(sbn!="" && sbn!=act->subjectName)
00377               ok=false;
00378               
00379        //activity tag
00380        if(sbtn!="" && !act->activityTagsNames.contains(sbtn))
00381               ok=false;
00382               
00383        //students
00384        if(stn!=""){
00385               bool ok2=false;
00386               for(QStringList::Iterator it=act->studentsNames.begin(); it!=act->studentsNames.end(); it++)
00387                      if(*it == stn){
00388                             ok2=true;
00389                             break;
00390                      }
00391               if(!ok2)
00392                      ok=false;
00393        }
00394        
00395        return ok;
00396 }
00397 
00398 void ModifyConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::filterChanged()
00399 {
00400        this->updateActivitiesListWidget();
00401 }
00402 
00403 void ModifyConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::updateActivitiesListWidget()
00404 {
00405        allActivitiesListWidget->clear();
00406        this->activitiesList.clear();
00407        
00408        for(int i=0; i<gt.rules.activitiesList.size(); i++){
00409               Activity* ac=gt.rules.activitiesList[i];
00410               if(filterOk(ac)){
00411                      allActivitiesListWidget->addItem(ac->getDescription(gt.rules));
00412                      this->activitiesList.append(ac->id);
00413               }
00414        }
00415        
00416        int q=allActivitiesListWidget->verticalScrollBar()->minimum();
00417        allActivitiesListWidget->verticalScrollBar()->setValue(q);
00418 }
00419 
00420 void ModifyConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::addActivity()
00421 {
00422        if(allActivitiesListWidget->currentRow()<0)
00423               return;
00424        int tmp=allActivitiesListWidget->currentRow();
00425        int _id=this->activitiesList.at(tmp);
00426        
00427        QString actName=allActivitiesListWidget->currentItem()->text();
00428        assert(actName!="");
00429        int i;
00430        //duplicate?
00431        for(i=0; i<selectedActivitiesListWidget->count(); i++)
00432               if(actName==selectedActivitiesListWidget->item(i)->text())
00433                      break;
00434        if(i<selectedActivitiesListWidget->count())
00435               return;
00436        selectedActivitiesListWidget->addItem(actName);
00437        selectedActivitiesListWidget->setCurrentRow(selectedActivitiesListWidget->count()-1);
00438        
00439        this->selectedActivitiesList.append(_id);
00440 }
00441 
00442 void ModifyConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::addAllActivities()
00443 {
00444        for(int tmp=0; tmp<allActivitiesListWidget->count(); tmp++){
00445               //int tmp=allActivitiesListWidget->currentRow();
00446               int _id=this->activitiesList.at(tmp);
00447        
00448               QString actName=allActivitiesListWidget->item(tmp)->text();
00449               assert(actName!="");
00450               int i;
00451               //duplicate?
00452               for(i=0; i<selectedActivitiesList.count(); i++)
00453                      if(selectedActivitiesList.at(i)==_id)
00454                             break;
00455               if(i<selectedActivitiesList.count())
00456                      continue;
00457               
00458               /*for(i=0; i<selectedActivitiesListWidget->count(); i++)
00459                      if(actName==selectedActivitiesListWidget->item(i)->text())
00460                             break;
00461               if(i<selectedActivitiesListWidget->count())
00462                      continue;*/
00463                      
00464               selectedActivitiesListWidget->addItem(actName);
00465               this->selectedActivitiesList.append(_id);
00466        }
00467 
00468        selectedActivitiesListWidget->setCurrentRow(selectedActivitiesListWidget->count()-1);
00469 }
00470 
00471 void ModifyConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::removeActivity()
00472 {
00473        if(selectedActivitiesListWidget->currentRow()<0 || selectedActivitiesListWidget->count()<=0)
00474               return;
00475        int tmp=selectedActivitiesListWidget->currentRow();
00476        
00477        selectedActivitiesList.removeAt(tmp);
00478 
00479        selectedActivitiesListWidget->setCurrentRow(-1);
00480        QListWidgetItem* item=selectedActivitiesListWidget->takeItem(tmp);
00481        delete item;
00482        if(tmp<selectedActivitiesListWidget->count())
00483               selectedActivitiesListWidget->setCurrentRow(tmp);
00484        else
00485               selectedActivitiesListWidget->setCurrentRow(selectedActivitiesListWidget->count()-1);
00486 }
00487 
00488 void ModifyConstraintActivitiesMaxSimultaneousInSelectedTimeSlotsForm::clear()
00489 {
00490        selectedActivitiesListWidget->clear();
00491        selectedActivitiesList.clear();
00492 }