Back to index

fet  5.18.0
removeredundantform.cpp
Go to the documentation of this file.
00001 //
00002 //
00003 // Description: This file is part of FET
00004 //
00005 //
00006 // Author: Lalescu Liviu <Please see http://lalescu.ro/liviu/ for details about contacting Liviu Lalescu (in particular, you can find here the e-mail address)>
00007 // Copyright (C) 2003 Liviu Lalescu <http://lalescu.ro/liviu/>
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 "removeredundantform.h"
00019 
00020 #include "timetable.h"
00021 
00022 extern Timetable gt;
00023 
00024 #include <QHash>
00025 #include <QList>
00026 #include <QQueue>
00027 
00028 #include <QMessageBox>
00029 
00030 #include <QPushButton>
00031 #include <QCheckBox>
00032 #include <QPlainTextEdit>
00033 #include <QLineEdit>
00034 #include <QHBoxLayout>
00035 #include <QVBoxLayout>
00036 
00037 RemoveRedundantForm::RemoveRedundantForm(QWidget* parent): QDialog(parent)
00038 {
00039        setupUi(this);
00040 
00041        centerWidgetOnScreen(this);
00042        restoreFETDialogGeometry(this);
00043        
00044        connect(buttonBox, SIGNAL(accepted()), this, SLOT(wasAccepted()));
00045        connect(buttonBox, SIGNAL(rejected()), this, SLOT(wasCanceled()));
00046 }
00047 
00048 RemoveRedundantForm::~RemoveRedundantForm()
00049 {
00050        saveFETDialogGeometry(this);
00051 }
00052 
00053 void RemoveRedundantForm::wasAccepted()
00054 {
00055        QMultiHash<int, int> adjMatrix;
00056 
00057        foreach(TimeConstraint* tc, gt.rules.timeConstraintsList){
00058               if(tc->weightPercentage==100.0){
00059                      if(tc->type==CONSTRAINT_ACTIVITIES_SAME_STARTING_TIME){
00060                             ConstraintActivitiesSameStartingTime* cst=(ConstraintActivitiesSameStartingTime*) tc;
00061                             
00062                             for(int i=1; i<cst->n_activities; i++){
00063                                    adjMatrix.insert(cst->activitiesId[0], cst->activitiesId[i]);
00064                                    adjMatrix.insert(cst->activitiesId[i], cst->activitiesId[0]);
00065                             }
00066                      }
00067                      else if(tc->type==CONSTRAINT_ACTIVITIES_SAME_STARTING_DAY){
00068                             ConstraintActivitiesSameStartingDay* csd=(ConstraintActivitiesSameStartingDay*) tc;
00069 
00070                             for(int i=1; i<csd->n_activities; i++){
00071                                    adjMatrix.insert(csd->activitiesId[0], csd->activitiesId[i]);
00072                                    adjMatrix.insert(csd->activitiesId[i], csd->activitiesId[0]);
00073                             }
00074                      }
00075               }
00076        }
00077        
00078        QHash<int, int> repr;
00079        
00080        QQueue<int> queue;
00081 
00082        foreach(Activity* act, gt.rules.activitiesList){
00083               int start=act->id;
00084               
00085               if(repr.value(start, -1)==-1){ //not visited
00086                      repr.insert(start, start);
00087                      queue.enqueue(start);
00088                      while(!queue.isEmpty()){
00089                             int crtHead=queue.dequeue();
00090                             assert(repr.value(crtHead, -1)==start);
00091                             QList<int> neighList=adjMatrix.values(crtHead);
00092                             foreach(int neigh, neighList){
00093                                    if(repr.value(neigh, -1)==-1){
00094                                           queue.enqueue(neigh);
00095                                           repr.insert(neigh, start);
00096                                    }
00097                                    else{
00098                                           assert(repr.value(neigh, -1)==start);
00099                                    }
00100                             }
00101                      }
00102               }
00103        }
00104        
00105        QList<ConstraintMinDaysBetweenActivities*> mdcList;
00106        
00107        foreach(TimeConstraint* tc, gt.rules.timeConstraintsList){
00108               if(tc->type==CONSTRAINT_MIN_DAYS_BETWEEN_ACTIVITIES){
00109                      mdcList.prepend((ConstraintMinDaysBetweenActivities*)tc); //inverse order, so earlier activities are not removed (the older ones are)
00110               }
00111        }
00112 
00113        QList<ConstraintMinDaysBetweenActivities*> toBeRemovedList;
00114        
00115        for(int i=0; i<mdcList.count()-1; i++){
00116               ConstraintMinDaysBetweenActivities* c1=mdcList.at(i);
00117               
00118               QList<int> a1List;
00119               for(int k=0; k<c1->n_activities; k++){
00120                      int m=repr.value(c1->activitiesId[k], -1);
00121                      assert(m>0);
00122                      a1List.append(m);
00123               }
00124               
00125               qSort(a1List);
00126               
00127               for(int j=i+1; j<mdcList.count(); j++){
00128                      ConstraintMinDaysBetweenActivities* c2=mdcList.at(j);
00129 
00130                      QList<int> a2List;
00131                      for(int k=0; k<c2->n_activities; k++){
00132                             int m=repr.value(c2->activitiesId[k], -1);
00133                             assert(m>0);
00134                             a2List.append(m);
00135                      }
00136                      
00137                      qSort(a2List);
00138                      
00139                      bool equal=true;
00140                      
00141                      if(a1List.count()!=a2List.count())
00142                             equal=false;
00143                      if(a1List!=a2List)
00144                             equal=false;
00145                      if(c1->minDays!=c2->minDays)
00146                             equal=false;
00147                             
00148                      //if(c1->weightPercentage!=c2->weightPercentage)
00149                      //     equal=false;                
00150                      //if(c1->consecutiveIfSameDay!=c2->consecutiveIfSameDay)
00151                      //     equal=false;
00152                      if(c1->weightPercentage > c2->weightPercentage){
00153                             if(!c1->consecutiveIfSameDay && c2->consecutiveIfSameDay){
00154                                    equal=false;
00155                             }
00156                      }
00157                      else if(c1->weightPercentage < c2->weightPercentage){
00158                             if(c1->consecutiveIfSameDay && !c2->consecutiveIfSameDay){
00159                                    equal=false;
00160                             }
00161                      }
00162                      else{
00163                             //
00164                      }
00165                      
00166                      if(equal){
00167                             if(c1->weightPercentage > c2->weightPercentage){
00168                                    ConstraintMinDaysBetweenActivities* tmp;
00169                                    tmp=mdcList[i];
00170                                    mdcList[i]=mdcList[j];
00171                                    mdcList[j]=tmp;
00172 
00173                                    c1=mdcList.at(i);
00174                                    c2=mdcList.at(j);
00175                             }
00176                             if(c1->weightPercentage==c2->weightPercentage && c1->consecutiveIfSameDay && !c2->consecutiveIfSameDay){
00177                                    ConstraintMinDaysBetweenActivities* tmp;
00178                                    tmp=mdcList[i];
00179                                    mdcList[i]=mdcList[j];
00180                                    mdcList[j]=tmp;
00181 
00182                                    c1=mdcList.at(i);
00183                                    c2=mdcList.at(j);
00184                             }
00185                             
00186                             assert( ! (c1->consecutiveIfSameDay && !c2->consecutiveIfSameDay) );
00187                             assert(c1->weightPercentage <= c2->weightPercentage);
00188                             
00189                             int kk=0;
00190                             for(kk=0; kk<toBeRemovedList.count(); kk++)
00191                                    if(toBeRemovedList.at(kk)->activitiesId[0] >= c1->activitiesId[0])
00192                                           break;
00193                             toBeRemovedList.insert(kk, c1);
00194                             
00195                             //toBeRemovedList.prepend(c1);
00196                             break;
00197                      }
00198               }
00199        }
00200 
00201 
00202 
00203 
00205        QDialog dialog(this);
00206        dialog.setWindowTitle(tr("Last confirmation needed"));
00207        
00208        QVBoxLayout* top=new QVBoxLayout(&dialog);
00209        QLabel* topLabel=new QLabel();
00210        topLabel->setText(tr("Operations that will be done:"));
00211        top->addWidget(topLabel);
00212        
00213        QPushButton* acceptPB=new QPushButton(tr("Accept"));
00214        QPushButton* cancelPB=new QPushButton(tr("Cancel"));
00215        QHBoxLayout* hl=new QHBoxLayout();
00216        hl->addStretch();
00217        hl->addWidget(acceptPB);
00218        hl->addWidget(cancelPB);
00219        
00220        QObject::connect(acceptPB, SIGNAL(clicked()), &dialog, SLOT(accept()));
00221        QObject::connect(cancelPB, SIGNAL(clicked()), &dialog, SLOT(reject()));
00222        
00223        QPlainTextEdit* removedText=new QPlainTextEdit();
00224        
00225        QString s=tr("The following time constraints will be inactivated (their weight will be made 0%):");
00226        s+="\n\n";
00227        foreach(ConstraintMinDaysBetweenActivities* ctr, toBeRemovedList){
00228               if(ctr->weightPercentage>0.0){
00229                      s+=ctr->getDetailedDescription(gt.rules);
00230                      s+="\n";
00231                      s+=tr("will be inactivated, by making its weight 0%");
00232                      s+="\n\n";
00233                      s+="---------------------------------";
00234                      s+="\n\n";
00235               }
00236        }
00237        
00238        removedText->setPlainText(s);
00239        removedText->setReadOnly(true);
00240        
00241        top->addWidget(removedText);
00242        
00243        top->addLayout(hl);
00244        
00245        const QString settingsName=QString("RemoveRedundantConstraintsLastConfirmationForm");
00246        
00247        dialog.resize(600, 400);
00248        centerWidgetOnScreen(&dialog);
00249        restoreFETDialogGeometry(&dialog, settingsName);
00250        
00251        acceptPB->setFocus();
00252        acceptPB->setDefault(true);
00253        
00254        setParentAndOtherThings(&dialog, this);
00255        int res=dialog.exec();
00256        saveFETDialogGeometry(&dialog, settingsName);
00257        
00258        if(res==QDialog::Rejected){
00259               toBeRemovedList.clear();
00260 
00261               return;
00262        }
00263 
00264        assert(res==QDialog::Accepted);
00265        
00266        gt.rules.internalStructureComputed=false;
00267        setRulesModifiedAndOtherThings(&gt.rules);
00268        
00269        foreach(ConstraintMinDaysBetweenActivities* mdc, toBeRemovedList)
00270               mdc->weightPercentage=0.0;
00271               
00272        toBeRemovedList.clear();
00273               
00274        this->accept();
00275 }
00276 
00277 void RemoveRedundantForm::wasCanceled()
00278 {
00279        this->reject();
00280 }
00281 
00282 void RemoveRedundantForm::on_removeRedundantCheckBox_toggled()
00283 {
00284        int k=removeRedundantCheckBox->isChecked();
00285        if(!k){
00286               removeRedundantCheckBox->setChecked(true);
00287               QMessageBox::information(this, tr("FET information"), tr("This box must remain checked, so that you can remove"
00288                " redundant constraints of type min days between activities"));
00289        }
00290 }