"Fossies" - the Fresh Open Source Software Archive

Member "fet-5.48.0/src/engine/import.cpp" (25 Nov 2020, 101426 Bytes) of package /linux/privat/fet-5.48.0.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "import.cpp" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 5.47.1_vs_5.48.0.

    1 /*
    2 File import.cpp
    3 */
    4 
    5 /***************************************************************************
    6                                 FET
    7                           -------------------
    8    copyright            : (C) by Lalescu Liviu
    9     email                : Please see https://lalescu.ro/liviu/ for details about contacting Liviu Lalescu (in particular, you can find here the e-mail address)
   10  ***************************************************************************
   11                           import.cpp  -  description
   12                              -------------------
   13     begin                : Mar 2008
   14     copyright            : (C) by Volker Dirr
   15                          : https://www.timetabling.de/
   16  ***************************************************************************
   17  *                                                                         *
   18  *   This program is free software: you can redistribute it and/or modify  *
   19  *   it under the terms of the GNU Affero General Public License as        *
   20  *   published by the Free Software Foundation, either version 3 of the    *
   21  *   License, or (at your option) any later version.                       *
   22  *                                                                         *
   23  ***************************************************************************/
   24 
   25 // Code contributed by Volker Dirr ( https://www.timetabling.de/ )
   26 
   27 //TODO: import days per week
   28 //TODO: import hours per day
   29 
   30 #include "import.h"
   31 
   32 #include <Qt>
   33 
   34 #include <QtGlobal>
   35 
   36 #if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
   37 #include <QtWidgets>
   38 #else
   39 #include <QtGui>
   40 #endif
   41 
   42 #include <QProgressDialog>
   43 
   44 #include <QSet>
   45 #include <QHash>
   46 #include <QList>
   47 #include <QPair>
   48 
   49 extern Timetable gt;
   50 
   51 // maybe I can add some of them again as parameter into function name?
   52 // it is not possible with fieldNumber and fieldName, because that conflicts with the using of command connect with chooseFieldsDialogUpdate (there are no parameters possible)
   53 static QString fileName;                // file name of the csv file
   54 
   55 static QString fieldSeparator=",";
   56 static QString textquote="\"";
   57 static QString setSeparator="+";
   58 
   59 static QString importThing;
   60 
   61 static int numberOfFields;              // number of fields per line of the csv file
   62 static QStringList fields;              // list of the fields of the first line of the csv file
   63 static bool head;                   // true = first line of csv file contain heading, so skip this line
   64 static QString fieldName[NUMBER_OF_FIELDS];     // field name (normally similar to the head)
   65 static int fieldNumber[NUMBER_OF_FIELDS];       // field number in the csv file
   66                             // fieldNumber >= 0 is the number of the field
   67                             // fieldNumber can also be IMPORT_DEFAULT_ITEM (==IMPORT_DEFAULT_ITEM). That mean that items of fieldList get the name of fieldDefaultItem (not of field[fieldNumber] from csv
   68                             // fieldNumber can also be DO_NOT_IMPORT (==-2). That mean that items are not imported into fieldList.
   69 static QStringList fieldList[NUMBER_OF_FIELDS]; // items of the fields (items from "field number")
   70 static QString fieldDefaultItem[NUMBER_OF_FIELDS];  // used, if fieldNumber == IMPORT_DEFAULT_ITEM
   71 static QString warnText;                // warnings about the csv file
   72 static QStringList dataWarning;         // warnings about the current conflicts between the csv file and the data that is already in memory
   73 static QString lastWarning;
   74 
   75 int Import::chooseWidth(int w)
   76 {
   77     int ww=w;
   78     if(ww>1000)
   79         ww=1000;
   80     
   81     return ww;
   82 }
   83 
   84 int Import::chooseHeight(int h)
   85 {
   86     int hh=h;
   87     if(hh>650)
   88         hh=650;
   89     
   90     return hh;
   91 }
   92 
   93 Import::Import()
   94 {
   95 }
   96 
   97 Import::~Import()
   98 {
   99 }
  100 
  101 void Import::prearrangement(){
  102     assert(gt.rules.initialized);
  103 
  104     fieldName[FIELD_LINE_NUMBER]=Import::tr("Line");
  105     fieldName[FIELD_YEAR_NAME]=Import::tr("Year");
  106     fieldName[FIELD_YEAR_NUMBER_OF_STUDENTS]=Import::tr("Number of Students per Year");
  107     fieldName[FIELD_GROUP_NAME]=Import::tr("Group");
  108     fieldName[FIELD_GROUP_NUMBER_OF_STUDENTS]=Import::tr("Number of Students per Group");
  109     fieldName[FIELD_SUBGROUP_NAME]=Import::tr("Subgroup");
  110     fieldName[FIELD_SUBGROUP_NUMBER_OF_STUDENTS]=Import::tr("Number of Students per Subgroup");
  111     fieldName[FIELD_SUBJECT_NAME]=Import::tr("Subject");
  112     fieldName[FIELD_ACTIVITY_TAG_NAME]=Import::tr("Activity Tag");
  113     fieldName[FIELD_TEACHER_NAME]=Import::tr("Teacher");
  114     fieldName[FIELD_BUILDING_NAME]=Import::tr("Building");
  115     fieldName[FIELD_ROOM_NAME]=Import::tr("Room Name");
  116     fieldName[FIELD_ROOM_CAPACITY]=Import::tr("Room Capacity");
  117     fieldName[FIELD_STUDENTS_SET]=Import::tr("Students Sets");
  118     fieldName[FIELD_TEACHERS_SET]=Import::tr("Teachers");
  119     fieldName[FIELD_TOTAL_DURATION]=Import::tr("Total Duration");
  120     fieldName[FIELD_SPLIT_DURATION]=Import::tr("Split Duration");
  121     fieldName[FIELD_MIN_DAYS]=Import::tr("Min Days");
  122     fieldName[FIELD_MIN_DAYS_WEIGHT]=Import::tr("Min Days Weight");
  123     fieldName[FIELD_MIN_DAYS_CONSECUTIVE]=Import::tr("Min Days Consecutive");
  124     fieldName[FIELD_ACTIVITY_TAGS_SET]=Import::tr("Activity Tags");
  125     for(int i=0; i<NUMBER_OF_FIELDS; i++){
  126         fieldNumber[i]=DO_NOT_IMPORT;
  127         fieldDefaultItem[i]="";
  128         fieldList[i].clear();
  129     }
  130     fieldNumber[FIELD_LINE_NUMBER]=IMPORT_DEFAULT_ITEM;
  131     fieldDefaultItem[FIELD_LINE_NUMBER]=Import::tr("line");
  132     dataWarning.clear();
  133     warnText.clear();
  134     lastWarning.clear();
  135 }
  136 
  137 
  138 //TODO: add this into the first function!? form too full?!
  139 ChooseFieldsDialog::ChooseFieldsDialog(QWidget *parent): QDialog(parent)
  140 {
  141     assert(fields.size()>0);
  142 
  143     this->setWindowTitle(tr("FET - Import from CSV file"));
  144     QGridLayout* chooseFieldsMainLayout=new QGridLayout(this);
  145 
  146     QVBoxLayout* fieldBox[NUMBER_OF_FIELDS];
  147     QHBoxLayout* fieldLine1[NUMBER_OF_FIELDS];
  148     QHBoxLayout* fieldLine2[NUMBER_OF_FIELDS];
  149     QHBoxLayout* fieldLine3[NUMBER_OF_FIELDS];
  150     QHBoxLayout* fieldLine3b[NUMBER_OF_FIELDS];
  151 
  152     int gridRow=0;
  153     int gridColumn=0;
  154     for(int i=1; i<NUMBER_OF_FIELDS; i++){
  155         assert(fieldNumber[i]==DO_NOT_IMPORT || fieldNumber[i]==IMPORT_DEFAULT_ITEM);
  156         fieldGroupBox[i] = new QGroupBox(Import::tr("Please specify the %1 field:").arg(fieldName[i]));
  157         fieldBox[i] = new QVBoxLayout();
  158         fieldRadio1[i] = new QRadioButton(Import::tr("Don't import \"%1\".").arg(fieldName[i]));
  159         fieldRadio2[i] = new QRadioButton(Import::tr("Import this field from CSV:"));
  160         
  161         //trick to keep the translation active, maybe we need it in the future
  162         QString s=Import::tr("Set always the same name:");
  163         Q_UNUSED(s);
  164         
  165         //fieldRadio3[i] = new QRadioButton(Import::tr("Set always the same name:"));
  166         fieldRadio3[i] = new QRadioButton(Import::tr("Set always the same value:")); //modified by Liviu on 18 March 2009
  167         fieldRadio3b[i] = new QRadioButton(Import::tr("Set always the same value:"));
  168 
  169         fieldLine1[i] = new QHBoxLayout();
  170         fieldLine1[i]->addWidget(fieldRadio1[i]);
  171         fieldBox[i]->addLayout(fieldLine1[i]);
  172         
  173         fieldLine2CB[i] = new QComboBox();
  174         fieldLine2CB[i]->setMaximumWidth(220);          //max
  175         fieldLine2CB[i]->insertItems(0,fields);
  176         fieldLine2[i] = new QHBoxLayout();
  177         fieldLine2[i]->addWidget(fieldRadio2[i]);
  178         fieldLine2[i]->addWidget(fieldLine2CB[i]);
  179         fieldBox[i]->addLayout(fieldLine2[i]);
  180         fieldRadio2[i]->setChecked(true);
  181 
  182         fieldLine3Text[i] = new QLineEdit(Import::tr("Please modify this text."));
  183 //      fieldLine3Text[i]->setMaximumWidth(220);        //max
  184         fieldLine3[i] = new QHBoxLayout();
  185         fieldLine3[i]->addWidget(fieldRadio3[i]);
  186         
  187         //Added by Liviu - 18 March 2009, so that the dialog looks nice when dialog is maximized
  188         
  189         //TODO: add this line or not???
  190         fieldLine3[i]->addStretch();
  191         //If you uncomment the line below, please include the header <QSizePolicy> at the beginning of the file (though it is probably just a matter of aesthetics).
  192         //fieldLine3Text[i]->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum);
  193         
  194         fieldLine3[i]->addWidget(fieldLine3Text[i]);
  195         fieldBox[i]->addLayout(fieldLine3[i]);
  196 
  197         fieldLine3bSpinBox[i] = new QSpinBox();
  198         fieldLine3bSpinBox[i]->setMaximumWidth(220);        //max
  199         fieldLine3b[i] = new QHBoxLayout();
  200         fieldLine3b[i]->addWidget(fieldRadio3b[i]);
  201         fieldLine3b[i]->addWidget(fieldLine3bSpinBox[i]);
  202         fieldBox[i]->addLayout(fieldLine3b[i]);
  203 
  204         fieldGroupBox[i]->setLayout(fieldBox[i]);
  205         chooseFieldsMainLayout->addWidget(fieldGroupBox[i], gridRow, gridColumn);
  206         if(fieldNumber[i]==DO_NOT_IMPORT)
  207             fieldGroupBox[i]->hide();
  208         else {
  209             if(gridColumn==1){
  210                 gridColumn=0;
  211                 gridRow++;
  212             } else
  213                 gridColumn++;
  214         }
  215 
  216         if(i==FIELD_YEAR_NAME || i==FIELD_TEACHER_NAME)
  217             fieldRadio1[i]->hide();
  218         if(i==FIELD_ROOM_CAPACITY){
  219             fieldRadio1[i]->hide();
  220             fieldLine3bSpinBox[i]->setMaximum(MAX_ROOM_CAPACITY);
  221             fieldLine3bSpinBox[i]->setMinimum(0);
  222             fieldLine3bSpinBox[i]->setValue(MAX_ROOM_CAPACITY);
  223             fieldRadio3b[i]->setChecked(true);
  224             fieldRadio3[i]->hide();
  225             fieldLine3Text[i]->hide();
  226         } else if(i==FIELD_YEAR_NUMBER_OF_STUDENTS || i==FIELD_GROUP_NUMBER_OF_STUDENTS || i==FIELD_SUBGROUP_NUMBER_OF_STUDENTS){
  227             fieldRadio1[i]->hide();
  228             fieldLine3bSpinBox[i]->setMaximum(MAX_TOTAL_SUBGROUPS);
  229             fieldLine3bSpinBox[i]->setMinimum(0);
  230             fieldLine3bSpinBox[i]->setValue(0);
  231             fieldRadio3b[i]->setChecked(true);
  232             fieldRadio3[i]->hide();
  233             fieldLine3Text[i]->hide();
  234         } else {
  235             fieldRadio3b[i]->hide();
  236             fieldLine3bSpinBox[i]->hide();
  237         }
  238         if(i==FIELD_SUBJECT_NAME){
  239             fieldRadio1[i]->hide();
  240             fieldRadio3[i]->hide();
  241             fieldLine3Text[i]->hide();
  242         }
  243         if(i==FIELD_ACTIVITY_TAG_NAME){
  244             fieldRadio1[i]->hide();
  245             fieldRadio3[i]->hide();
  246             fieldLine3Text[i]->hide();
  247         }
  248         if(i==FIELD_ROOM_NAME){
  249             fieldRadio3[i]->hide();
  250             fieldLine3Text[i]->hide();
  251         }
  252         
  253         if(i==FIELD_TOTAL_DURATION){
  254             fieldRadio1[i]->hide();
  255             fieldLine3Text[i]->setText("1");
  256         }
  257         if(i==FIELD_SPLIT_DURATION){
  258             fieldRadio1[i]->hide();
  259             fieldLine3Text[i]->setText("1");
  260         }
  261         if(i==FIELD_MIN_DAYS){
  262             fieldRadio1[i]->hide();
  263             fieldLine3Text[i]->setText("1");
  264         }
  265         if(i==FIELD_MIN_DAYS_WEIGHT){
  266             fieldRadio1[i]->hide();
  267             fieldLine3Text[i]->setText("95");
  268         }
  269         if(i==FIELD_MIN_DAYS_CONSECUTIVE){
  270             fieldRadio1[i]->hide();
  271             fieldLine3Text[i]->setText("1");
  272         }
  273     }
  274 
  275     gridRow++;
  276     /*
  277     pb=new QPushButton(tr("OK"));
  278     chooseFieldsMainLayout->addWidget(pb,gridRow,1);
  279     cancelpb=new QPushButton(tr("Cancel"));
  280     chooseFieldsMainLayout->addWidget(cancelpb,gridRow,2);*/
  281     pb=new QPushButton(tr("OK"));
  282     cancelpb=new QPushButton(tr("Cancel"));
  283     buttonsLayout=new QHBoxLayout();
  284     buttonsLayout->addStretch();
  285     buttonsLayout->addWidget(pb);
  286     buttonsLayout->addWidget(cancelpb);
  287     chooseFieldsMainLayout->addLayout(buttonsLayout,gridRow,1);
  288 
  289     chooseFieldsDialogUpdateRadio1();
  290     chooseFieldsDialogUpdateRadio2();
  291     chooseFieldsDialogUpdateRadio3();
  292     chooseFieldsDialogUpdateRadio3b();
  293 
  294     //connect(pb, SIGNAL(clicked()), this, SLOT(accept()));
  295     connect(pb, SIGNAL(clicked()), this, SLOT(chooseFieldsDialogClose()));
  296     connect(cancelpb, SIGNAL(clicked()), this, SLOT(reject()));
  297     for(int i=1; i<NUMBER_OF_FIELDS; i++){
  298         connect(fieldRadio1[i], SIGNAL(toggled(bool)), this, SLOT(chooseFieldsDialogUpdateRadio1()));
  299         connect(fieldRadio2[i], SIGNAL(toggled(bool)), this, SLOT(chooseFieldsDialogUpdateRadio2()));
  300         connect(fieldRadio3[i], SIGNAL(toggled(bool)), this, SLOT(chooseFieldsDialogUpdateRadio3()));
  301         connect(fieldRadio3b[i], SIGNAL(toggled(bool)), this, SLOT(chooseFieldsDialogUpdateRadio3b()));
  302         connect(fieldLine3Text[i], SIGNAL(textChanged(QString)), this, SLOT(chooseFieldsDialogUpdateLine3Text()));
  303     }
  304     
  305     pb->setDefault(true);
  306     pb->setFocus();
  307     
  308     //_settingsName=settingsName;
  309     //restoreFETDialogGeometry(this, _settingsName);
  310 }
  311 
  312 ChooseFieldsDialog::~ChooseFieldsDialog()
  313 {
  314     //saveFETDialogGeometry(this, _settingsName);
  315 }
  316 
  317 void ChooseFieldsDialog::chooseFieldsDialogUpdateRadio1(){
  318     if(fieldRadio1[FIELD_GROUP_NAME]->isChecked()){
  319         fieldRadio1[FIELD_GROUP_NUMBER_OF_STUDENTS]->setChecked(true);
  320         fieldRadio1[FIELD_SUBGROUP_NAME]->setChecked(true);
  321         fieldRadio1[FIELD_SUBGROUP_NUMBER_OF_STUDENTS]->setChecked(true);
  322         fieldGroupBox[FIELD_GROUP_NUMBER_OF_STUDENTS]->setDisabled(true);
  323         fieldGroupBox[FIELD_SUBGROUP_NUMBER_OF_STUDENTS]->setDisabled(true);
  324         fieldGroupBox[FIELD_SUBGROUP_NAME]->setDisabled(true);
  325     }
  326     if(fieldRadio1[FIELD_SUBGROUP_NAME]->isChecked()){
  327         fieldRadio1[FIELD_SUBGROUP_NUMBER_OF_STUDENTS]->setChecked(true);
  328         fieldGroupBox[FIELD_SUBGROUP_NUMBER_OF_STUDENTS]->setDisabled(true);
  329     }
  330     if(fieldRadio1[FIELD_ROOM_NAME]->isChecked()){
  331         fieldRadio1[FIELD_ROOM_CAPACITY]->setChecked(true);
  332         fieldGroupBox[FIELD_ROOM_CAPACITY]->setDisabled(true);
  333     }
  334     if(fieldRadio1[FIELD_BUILDING_NAME]->isChecked()&&fieldRadio1[FIELD_ROOM_NAME]->isChecked()){
  335         pb->setDisabled(true);
  336     }
  337     if((fieldRadio1[FIELD_BUILDING_NAME]->isChecked()&&!fieldRadio1[FIELD_ROOM_NAME]->isChecked()&&fieldLine3Text[FIELD_BUILDING_NAME]->displayText()!="")
  338         ||(!fieldRadio1[FIELD_BUILDING_NAME]->isChecked()&&fieldRadio1[FIELD_ROOM_NAME]->isChecked()&&fieldLine3Text[FIELD_BUILDING_NAME]->displayText()!="")){
  339         pb->setDisabled(false);
  340     }
  341 }
  342 
  343 
  344 void ChooseFieldsDialog::chooseFieldsDialogUpdateRadio2(){
  345     if(fieldRadio2[FIELD_GROUP_NAME]->isChecked()){
  346         fieldGroupBox[FIELD_SUBGROUP_NAME]->setDisabled(false);
  347         fieldGroupBox[FIELD_SUBGROUP_NUMBER_OF_STUDENTS]->setDisabled(false);
  348         fieldGroupBox[FIELD_GROUP_NUMBER_OF_STUDENTS]->setDisabled(false);
  349         fieldGroupBox[FIELD_SUBGROUP_NUMBER_OF_STUDENTS]->setDisabled(false);
  350         if(fieldRadio1[FIELD_GROUP_NUMBER_OF_STUDENTS]->isChecked())
  351             fieldRadio3b[FIELD_GROUP_NUMBER_OF_STUDENTS]->setChecked(true);
  352         if(fieldRadio1[FIELD_SUBGROUP_NUMBER_OF_STUDENTS]->isChecked())
  353             fieldRadio3b[FIELD_SUBGROUP_NUMBER_OF_STUDENTS]->setChecked(true);
  354     }
  355     if(fieldRadio2[FIELD_ROOM_NAME]->isChecked()){
  356         if(fieldRadio1[FIELD_ROOM_CAPACITY]->isChecked())
  357             fieldRadio3b[FIELD_ROOM_CAPACITY]->setChecked(true);
  358         fieldGroupBox[FIELD_ROOM_CAPACITY]->setDisabled(false);
  359     }
  360 }
  361 
  362 void ChooseFieldsDialog::chooseFieldsDialogUpdateRadio3(){
  363     if(fieldRadio3[FIELD_GROUP_NAME]->isChecked()){
  364         fieldGroupBox[FIELD_SUBGROUP_NAME]->setDisabled(false);
  365         fieldGroupBox[FIELD_SUBGROUP_NUMBER_OF_STUDENTS]->setDisabled(false);
  366         fieldGroupBox[FIELD_GROUP_NUMBER_OF_STUDENTS]->setDisabled(false);
  367         fieldGroupBox[FIELD_SUBGROUP_NUMBER_OF_STUDENTS]->setDisabled(false);
  368         if(fieldRadio1[FIELD_GROUP_NUMBER_OF_STUDENTS]->isChecked())
  369             fieldRadio3b[FIELD_GROUP_NUMBER_OF_STUDENTS]->setChecked(true);
  370         if(fieldRadio1[FIELD_SUBGROUP_NUMBER_OF_STUDENTS]->isChecked())
  371             fieldRadio3b[FIELD_SUBGROUP_NUMBER_OF_STUDENTS]->setChecked(true);
  372     }
  373     if(fieldRadio3[FIELD_ROOM_NAME]->isChecked()){
  374         if(fieldRadio1[FIELD_ROOM_CAPACITY]->isChecked())
  375             fieldRadio3b[FIELD_ROOM_CAPACITY]->setChecked(true);
  376         fieldGroupBox[FIELD_ROOM_CAPACITY]->setDisabled(false);
  377     }
  378 }
  379 
  380 void ChooseFieldsDialog::chooseFieldsDialogUpdateRadio3b(){
  381     if(fieldRadio3b[FIELD_GROUP_NAME]->isChecked()){
  382         fieldGroupBox[FIELD_SUBGROUP_NAME]->setDisabled(false);
  383         fieldGroupBox[FIELD_SUBGROUP_NUMBER_OF_STUDENTS]->setDisabled(false);
  384         fieldGroupBox[FIELD_GROUP_NUMBER_OF_STUDENTS]->setDisabled(false);
  385         fieldGroupBox[FIELD_SUBGROUP_NUMBER_OF_STUDENTS]->setDisabled(false);
  386         if(fieldRadio1[FIELD_GROUP_NUMBER_OF_STUDENTS]->isChecked())
  387             fieldRadio3b[FIELD_GROUP_NUMBER_OF_STUDENTS]->setChecked(true);
  388         if(fieldRadio1[FIELD_SUBGROUP_NUMBER_OF_STUDENTS]->isChecked())
  389             fieldRadio3b[FIELD_SUBGROUP_NUMBER_OF_STUDENTS]->setChecked(true);
  390     }
  391     if(fieldRadio3b[FIELD_ROOM_NAME]->isChecked()){
  392         if(fieldRadio1[FIELD_ROOM_CAPACITY]->isChecked())
  393             fieldRadio3b[FIELD_ROOM_CAPACITY]->setChecked(true);
  394         fieldGroupBox[FIELD_ROOM_CAPACITY]->setDisabled(false);
  395     }
  396 }
  397 
  398 
  399 void ChooseFieldsDialog::chooseFieldsDialogUpdateLine3Text(){
  400     bool textOK=true;
  401     for(int i=1; i<NUMBER_OF_FIELDS; i++){
  402         if(fieldLine3Text[i]->displayText()=="")
  403             textOK=false;
  404     }
  405     //by Liviu - always enabled
  406     if(1 || textOK)
  407         pb->setDisabled(false);
  408     else
  409         pb->setDisabled(true);
  410 }
  411 
  412 void ChooseFieldsDialog::chooseFieldsDialogClose(){
  413     for(int i=1; i<NUMBER_OF_FIELDS; i++){
  414         if(fieldNumber[i]!=DO_NOT_IMPORT){
  415             if(fieldRadio1[i]->isChecked()){
  416                 fieldNumber[i]=DO_NOT_IMPORT;
  417             }
  418             if(fieldRadio2[i]->isChecked()){
  419                 fieldNumber[i]=fieldLine2CB[i]->currentIndex();
  420                 assert(fieldNumber[i]<fields.size());
  421                 assert(fieldNumber[i]>=0);
  422             }
  423             if(fieldRadio3[i]->isChecked()){
  424                 fieldNumber[i]=IMPORT_DEFAULT_ITEM;
  425                 //fieldName[i]=fieldLine3CB[i]->currentText();
  426                 fieldDefaultItem[i]=fieldLine3Text[i]->displayText();
  427             }
  428             if(fieldRadio3b[i]->isChecked()){
  429                 fieldNumber[i]=IMPORT_DEFAULT_ITEM;
  430                 fieldDefaultItem[i]=fieldLine3bSpinBox[i]->cleanText();
  431             }
  432         }
  433     }
  434     
  435     this->accept();
  436 }
  437 
  438 LastWarningsDialog::LastWarningsDialog(QWidget *parent): QDialog(parent)
  439 {
  440     this->setWindowTitle(tr("FET - import %1 comment", "The comment of the importing of the category named %1").arg(importThing));
  441     QVBoxLayout* lastWarningsMainLayout=new QVBoxLayout(this);
  442 
  443     QPlainTextEdit* lastWarningsText=new QPlainTextEdit();
  444     lastWarningsText->setMinimumWidth(500);             //width
  445     lastWarningsText->setMinimumHeight(250);
  446     lastWarningsText->setReadOnly(true);
  447     lastWarningsText->setWordWrapMode(QTextOption::NoWrap);
  448     lastWarningsText->setPlainText(lastWarning);
  449 
  450     //Start Buttons
  451     QPushButton* pb1=new QPushButton(tr("&OK"));
  452     //pb1->setAutoDefault(true);
  453 
  454     QHBoxLayout* hl=new QHBoxLayout();
  455     hl->addStretch();
  456     hl->addWidget(pb1);
  457 
  458     //Start adding all into main layout
  459     lastWarningsMainLayout->addWidget(lastWarningsText);
  460     lastWarningsMainLayout->addLayout(hl);
  461 
  462     QObject::connect(pb1, SIGNAL(clicked()), this, SLOT(accept()));
  463     
  464     //pb1->setDefault(true);
  465 
  466     pb1->setDefault(true);
  467     pb1->setFocus();
  468 }
  469 
  470 LastWarningsDialog::~LastWarningsDialog()
  471 {
  472 }
  473 
  474 // private funtions ---------------------------------------------------------------------------------------------------
  475 int Import::getFileSeparatorFieldsAndHead(QWidget* parent, QDialog* &newParent){
  476     assert(gt.rules.initialized);
  477     
  478     newParent=((QDialog*)parent);
  479     
  480     QString settingsName;
  481 
  482     if(fieldNumber[FIELD_ACTIVITY_TAG_NAME]==IMPORT_DEFAULT_ITEM){
  483         importThing=Import::tr("activity tags");
  484         settingsName=QString("ImportActivityTagsSelectSeparatorsDialog");
  485     }
  486     if(fieldNumber[FIELD_ROOM_NAME]==IMPORT_DEFAULT_ITEM){
  487         importThing=Import::tr("buildings and rooms");
  488         settingsName=QString("ImportBuildingsRoomsSelectSeparatorsDialog");
  489     }
  490     if(fieldNumber[FIELD_TEACHER_NAME]==IMPORT_DEFAULT_ITEM){
  491         importThing=Import::tr("teachers");
  492         settingsName=QString("ImportTeachersSelectSeparatorsDialog");
  493     }
  494     if(fieldNumber[FIELD_SUBJECT_NAME]==IMPORT_DEFAULT_ITEM){
  495         importThing=Import::tr("subjects");
  496         settingsName=QString("ImportSubjectsSelectSeparatorsDialog");
  497     }
  498     if(fieldNumber[FIELD_YEAR_NAME]==IMPORT_DEFAULT_ITEM){
  499         importThing=Import::tr("years, groups and subgroups");
  500         settingsName=QString("ImportYearsGroupsSubgroupsSelectSeparatorsDialog");
  501     }
  502     if(fieldNumber[FIELD_STUDENTS_SET]==IMPORT_DEFAULT_ITEM){
  503         importThing=Import::tr("activities");
  504         settingsName=QString("ImportActivitiesSelectSeparatorsDialog");
  505     }
  506 
  507     fileName=QFileDialog::getOpenFileName(parent, Import::tr("FET - Import %1 from CSV file").arg(importThing), IMPORT_DIRECTORY,
  508         Import::tr("Text Files")+" (*.csv *.dat *.txt)" + ";;" + Import::tr("All Files") + " (*)");
  509 
  510     const QString NO_SEPARATOR_TRANSLATED=Import::tr("no separator");
  511     fieldSeparator=NO_SEPARATOR_TRANSLATED; //needed, because a csv file contain maybe just one field!
  512     const QString NO_TEXTQUOTE_TRANSLATED=Import::tr("no textquote");
  513     textquote=NO_TEXTQUOTE_TRANSLATED;
  514     fields.clear();
  515     QFile file(fileName);
  516     if(fileName.isEmpty()){
  517         return false;
  518     }
  519     if(!file.open(QIODevice::ReadOnly|QIODevice::Text)){
  520         return false;
  521     }
  522     QTextStream in(&file);
  523 #if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
  524     in.setEncoding(QStringConverter::Utf8);
  525 #else
  526     in.setCodec("UTF-8");
  527 #endif
  528     QString line = in.readLine();
  529     file.close();
  530     
  531     if(line.size()<=0){
  532         QMessageBox::warning(parent, tr("FET warning"), tr("The first line of the file is empty. Please fix this."));
  533         return false;
  534     }
  535     
  536     if(fieldNumber[FIELD_ACTIVITY_TAG_NAME]==IMPORT_DEFAULT_ITEM
  537         && line.contains("\"Activity Tag\"")
  538         && line.size()<=QString("\"Activity Tag\"").length()+1
  539         && line.size()>=QString("\"Activity Tag\"").length()){
  540         fieldNumber[FIELD_ACTIVITY_TAG_NAME]=0;
  541         head=true;
  542         fieldSeparator=",";
  543         textquote="\"";
  544         fields<<line;
  545         return true;
  546     }
  547     
  548     if(fieldNumber[FIELD_ACTIVITY_TAG_NAME]==IMPORT_DEFAULT_ITEM
  549         && line.contains("Activity Tag")
  550         && line.size()<=QString("Activity Tag").length()+1
  551         && line.size()>=QString("Activity Tag").length()){
  552         fieldNumber[FIELD_ACTIVITY_TAG_NAME]=0;
  553         head=true;
  554         fieldSeparator=",";
  555         textquote="";
  556         fields<<line;
  557         return true;
  558     }
  559 
  560     if(fieldNumber[FIELD_ROOM_NAME]==IMPORT_DEFAULT_ITEM
  561         && line.contains("\"Room\",\"Room Capacity\",\"Building\"")
  562         && line.size()<=QString("\"Room\",\"Room Capacity\",\"Building\"").length()+1
  563         && line.size()>=QString("\"Room\",\"Room Capacity\",\"Building\"").length()){
  564         fieldNumber[FIELD_BUILDING_NAME]=2;
  565         fieldNumber[FIELD_ROOM_NAME]=0;
  566         fieldNumber[FIELD_ROOM_CAPACITY]=1;
  567         head=true;
  568         fieldSeparator=",";
  569         textquote="\"";
  570         fields=line.split(fieldSeparator);
  571         return true;
  572     }
  573     
  574     if(fieldNumber[FIELD_ROOM_NAME]==IMPORT_DEFAULT_ITEM
  575         && line.contains("Room,Room Capacity,Building")
  576         && line.size()<=QString("Room,Room Capacity,Building").length()+1
  577         && line.size()>=QString("Room,Room Capacity,Building").length()){
  578         fieldNumber[FIELD_BUILDING_NAME]=2;
  579         fieldNumber[FIELD_ROOM_NAME]=0;
  580         fieldNumber[FIELD_ROOM_CAPACITY]=1;
  581         head=true;
  582         fieldSeparator=",";
  583         textquote="";
  584         fields=line.split(fieldSeparator);
  585         return true;
  586     }
  587 
  588     if(fieldNumber[FIELD_TEACHER_NAME]==IMPORT_DEFAULT_ITEM
  589         && line.contains("\"Teacher\"")
  590         && line.size()<=QString("\"Teacher\"").length()+1
  591         && line.size()>=QString("\"Teacher\"").length()){
  592         fieldNumber[FIELD_TEACHER_NAME]=0;
  593         head=true;
  594         fieldSeparator=",";
  595         textquote="\"";
  596         fields<<line;
  597         return true;
  598     }
  599     
  600     if(fieldNumber[FIELD_TEACHER_NAME]==IMPORT_DEFAULT_ITEM
  601         && line.contains("Teacher")
  602         && line.size()<=QString("Teacher").length()+1
  603         && line.size()>=QString("Teacher").length()){
  604         fieldNumber[FIELD_TEACHER_NAME]=0;
  605         head=true;
  606         fieldSeparator=",";
  607         textquote="";
  608         fields<<line;
  609         return true;
  610     }
  611 
  612     if(fieldNumber[FIELD_SUBJECT_NAME]==IMPORT_DEFAULT_ITEM
  613         && line.contains("\"Subject\"")
  614         && line.size()<=QString("\"Subject\"").length()+1
  615         && line.size()>=QString("\"Subject\"").length()){
  616         fieldNumber[FIELD_SUBJECT_NAME]=0;
  617         head=true;
  618         fieldSeparator=",";
  619         textquote="\"";
  620         fields<<line;
  621         return true;
  622     }
  623     
  624     if(fieldNumber[FIELD_SUBJECT_NAME]==IMPORT_DEFAULT_ITEM
  625         && line.contains("Subject")
  626         && line.size()<=QString("Subject").length()+1
  627         && line.size()>=QString("Subject").length()){
  628         fieldNumber[FIELD_SUBJECT_NAME]=0;
  629         head=true;
  630         fieldSeparator=",";
  631         textquote="";
  632         fields<<line;
  633         return true;
  634     }
  635 
  636     if(fieldNumber[FIELD_YEAR_NAME]==IMPORT_DEFAULT_ITEM
  637         && line.contains("\"Year\",\"Number of Students per Year\",\"Group\",\"Number of Students per Group\",\"Subgroup\",\"Number of Students per Subgroup\"")
  638         && line.size()<=QString("\"Year\",\"Number of Students per Year\",\"Group\",\"Number of Students per Group\",\"Subgroup\",\"Number of Students per Subgroup\"").length()+1
  639         && line.size()>=QString("\"Year\",\"Number of Students per Year\",\"Group\",\"Number of Students per Group\",\"Subgroup\",\"Number of Students per Subgroup\"").length()){
  640         fieldNumber[FIELD_YEAR_NAME]=0;
  641         fieldNumber[FIELD_YEAR_NUMBER_OF_STUDENTS]=1;
  642         fieldNumber[FIELD_GROUP_NAME]=2;
  643         fieldNumber[FIELD_GROUP_NUMBER_OF_STUDENTS]=3;
  644         fieldNumber[FIELD_SUBGROUP_NAME]=4;
  645         fieldNumber[FIELD_SUBGROUP_NUMBER_OF_STUDENTS]=5;
  646         head=true;
  647         fieldSeparator=",";
  648         textquote="\"";
  649         fields=line.split(fieldSeparator);
  650         return true;
  651     }
  652     
  653     if(fieldNumber[FIELD_YEAR_NAME]==IMPORT_DEFAULT_ITEM
  654         && line.contains("Year,Number of Students per Year,Group,Number of Students per Group,Subgroup,Number of Students per Subgroup")
  655         && line.size()<=QString("Year,Number of Students per Year,Group,Number of Students per Group,Subgroup,Number of Students per Subgroup").length()+1
  656         && line.size()>=QString("Year,Number of Students per Year,Group,Number of Students per Group,Subgroup,Number of Students per Subgroup").length()){
  657         fieldNumber[FIELD_YEAR_NAME]=0;
  658         fieldNumber[FIELD_YEAR_NUMBER_OF_STUDENTS]=1;
  659         fieldNumber[FIELD_GROUP_NAME]=2;
  660         fieldNumber[FIELD_GROUP_NUMBER_OF_STUDENTS]=3;
  661         fieldNumber[FIELD_SUBGROUP_NAME]=4;
  662         fieldNumber[FIELD_SUBGROUP_NUMBER_OF_STUDENTS]=5;
  663         head=true;
  664         fieldSeparator=",";
  665         textquote="";
  666         fields=line.split(fieldSeparator);
  667         return true;
  668     }
  669 
  670     if(fieldNumber[FIELD_STUDENTS_SET]==IMPORT_DEFAULT_ITEM
  671         && line.contains("\"Students Sets\",\"Subject\",\"Teachers\",\"Activity Tags\",\"Total Duration\",\"Split Duration\",\"Min Days\",\"Weight\",\"Consecutive\"")
  672         && line.size()<=QString("\"Students Sets\",\"Subject\",\"Teachers\",\"Activity Tags\",\"Total Duration\",\"Split Duration\",\"Min Days\",\"Weight\",\"Consecutive\"").length()+1
  673         && line.size()>=QString("\"Students Sets\",\"Subject\",\"Teachers\",\"Activity Tags\",\"Total Duration\",\"Split Duration\",\"Min Days\",\"Weight\",\"Consecutive\"").length()){
  674         fieldNumber[FIELD_ACTIVITY_TAGS_SET]=3;
  675         fieldNumber[FIELD_SUBJECT_NAME]=1;
  676         fieldNumber[FIELD_STUDENTS_SET]=0;
  677         fieldNumber[FIELD_TEACHERS_SET]=2;
  678         fieldNumber[FIELD_TOTAL_DURATION]=4;
  679         fieldNumber[FIELD_SPLIT_DURATION]=5;
  680         fieldNumber[FIELD_MIN_DAYS]=6;
  681         fieldNumber[FIELD_MIN_DAYS_WEIGHT]=7;
  682         fieldNumber[FIELD_MIN_DAYS_CONSECUTIVE]=8;
  683         head=true;
  684         fieldSeparator=",";
  685         textquote="\"";
  686         fields=line.split(fieldSeparator);
  687         return true;
  688     }
  689     
  690     if(fieldNumber[FIELD_STUDENTS_SET]==IMPORT_DEFAULT_ITEM
  691         && line.contains("Students Sets,Subject,Teachers,Activity Tags,Total Duration,Split Duration,Min Days,Weight,Consecutive")
  692         && line.size()<=QString("Students Sets,Subject,Teachers,Activity Tags,Total Duration,Split Duration,Min Days,Weight,Consecutive").length()+1
  693         && line.size()>=QString("Students Sets,Subject,Teachers,Activity Tags,Total Duration,Split Duration,Min Days,Weight,Consecutive").length()){
  694         fieldNumber[FIELD_ACTIVITY_TAGS_SET]=3;
  695         fieldNumber[FIELD_SUBJECT_NAME]=1;
  696         fieldNumber[FIELD_STUDENTS_SET]=0;
  697         fieldNumber[FIELD_TEACHERS_SET]=2;
  698         fieldNumber[FIELD_TOTAL_DURATION]=4;
  699         fieldNumber[FIELD_SPLIT_DURATION]=5;
  700         fieldNumber[FIELD_MIN_DAYS]=6;
  701         fieldNumber[FIELD_MIN_DAYS_WEIGHT]=7;
  702         fieldNumber[FIELD_MIN_DAYS_CONSECUTIVE]=8;
  703         head=true;
  704         fieldSeparator=",";
  705         textquote="";
  706         fields=line.split(fieldSeparator);
  707         return true;
  708     }
  709 
  710     QStringList separators;
  711     QStringList textquotes;
  712     separators<<fieldSeparator;
  713     const int NO_SEPARATOR_POS=0; //it is the first element. It may have length > 1 QChar
  714     textquotes<<textquote;
  715     const int NO_TEXTQUOTE_POS=0; //it is the first element. It may have length > 1 QChar
  716     for(int i=0; i<line.size();i++){
  717         //if(!(line.at(i)>='A'&&line.at(i)<='Z')&&!(line.at(i)>='a'&&line.at(i)<='z')&&!(line.at(i)>='0'&&line.at(i)<='9')&&!separators.contains(line.at(i))){
  718         if(!(line.at(i).isLetterOrNumber())&&!separators.contains(line.at(i))){
  719             separators<<line.at(i);
  720             //careful: if you intend to add strings longer than one QChar, take care of assert in line 647 (below in the same function) (fieldSeparator.size()==1)
  721         }
  722         if(!(line.at(i).isLetterOrNumber())&&!textquotes.contains(line.at(i))){
  723             textquotes<<line.at(i);
  724             //careful: if you intend to add strings longer than one QChar, take care of assert in line 659 (below in the same function) (textquote.size()==1)
  725         }
  726     }
  727 
  728     newParent=new QDialog(parent);
  729     QDialog& separatorsDialog=(*newParent);
  730     separatorsDialog.setWindowTitle(Import::tr("FET - Import %1 from CSV file").arg(importThing));
  731     QVBoxLayout* separatorsMainLayout=new QVBoxLayout(&separatorsDialog);
  732 
  733     QHBoxLayout* top=new QHBoxLayout();
  734     QLabel* topText=new QLabel();
  735 
  736     int tmpi=fileName.lastIndexOf(FILE_SEP);
  737     tmpi=fileName.size()-tmpi-1;
  738     QString shortFileName=fileName.right(tmpi);
  739     topText->setText(Import::tr("The first line of file\n%1\nis:").arg(shortFileName));
  740     top->addWidget(topText);
  741     top->addStretch();
  742     QPlainTextEdit* textOfFirstLine=new QPlainTextEdit();
  743     textOfFirstLine->setReadOnly(true);
  744     textOfFirstLine->setPlainText(line);
  745 
  746     QGroupBox* separatorsGroupBox = new QGroupBox(Import::tr("Please specify the used separator between fields:"));
  747     QComboBox* separatorsCB=NULL;
  748     if(separators.size()>1){
  749         QHBoxLayout* separatorBoxChoose=new QHBoxLayout();
  750         separatorsCB=new QComboBox();
  751         
  752         QLabel* separatorTextChoose=new QLabel();
  753         separatorTextChoose->setText(Import::tr("Used field separator:"));
  754         separatorsCB->insertItems(0,separators);
  755         separatorBoxChoose->addWidget(separatorTextChoose);
  756         separatorBoxChoose->addWidget(separatorsCB);
  757         separatorsGroupBox->setLayout(separatorBoxChoose);
  758     }
  759 
  760     QGroupBox* textquoteGroupBox = new QGroupBox(Import::tr("Please specify the used text quote of text fields:"));
  761     QComboBox* textquoteCB=NULL;
  762     if(textquotes.size()>1){
  763         QHBoxLayout* textquoteBoxChoose=new QHBoxLayout();
  764         textquoteCB=new QComboBox();
  765         
  766         QLabel* textquoteTextChoose=new QLabel();
  767         textquoteTextChoose->setText(Import::tr("Used textquote:"));
  768         textquoteCB->insertItems(0,textquotes);
  769         textquoteBoxChoose->addWidget(textquoteTextChoose);
  770         textquoteBoxChoose->addWidget(textquoteCB);
  771         textquoteGroupBox->setLayout(textquoteBoxChoose);
  772     }
  773 
  774     QGroupBox* firstLineGroupBox = new QGroupBox(Import::tr("Please specify the contents of the first line:"));
  775     QVBoxLayout* firstLineChooseBox=new QVBoxLayout();
  776     QRadioButton* firstLineRadio1 = new QRadioButton(Import::tr("The first line is the heading. Don't import that line."));
  777     QRadioButton* firstLineRadio2 = new QRadioButton(Import::tr("The first line contains data. Import that line."));
  778     firstLineRadio1->setChecked(true);
  779     firstLineChooseBox->addWidget(firstLineRadio1);
  780     firstLineChooseBox->addWidget(firstLineRadio2);
  781     firstLineGroupBox->setLayout(firstLineChooseBox);
  782 
  783     QPushButton* pb=new QPushButton(tr("OK"));
  784     QPushButton* cancelpb=new QPushButton(tr("Cancel"));
  785     QHBoxLayout* hl=new QHBoxLayout();
  786     hl->addStretch();
  787     hl->addWidget(pb);
  788     hl->addWidget(cancelpb);
  789     
  790     separatorsMainLayout->addLayout(top);
  791     separatorsMainLayout->addWidget(textOfFirstLine);
  792     if(separators.size()>1){
  793         separatorsMainLayout->addWidget(separatorsGroupBox);
  794         separatorsMainLayout->addWidget(textquoteGroupBox);
  795     }
  796     else{
  797         delete separatorsGroupBox;
  798         delete textquoteGroupBox;
  799     }
  800     separatorsMainLayout->addWidget(firstLineGroupBox);
  801     separatorsMainLayout->addLayout(hl);
  802     QObject::connect(pb, SIGNAL(clicked()), &separatorsDialog, SLOT(accept()));
  803     QObject::connect(cancelpb, SIGNAL(clicked()), &separatorsDialog, SLOT(reject()));
  804     
  805     pb->setDefault(true);
  806     pb->setFocus();
  807     
  808     int w=chooseWidth(separatorsDialog.sizeHint().width());
  809     int h=chooseHeight(separatorsDialog.sizeHint().height());
  810     separatorsDialog.resize(w,h);
  811     centerWidgetOnScreen(&separatorsDialog);
  812     restoreFETDialogGeometry(&separatorsDialog, settingsName);
  813     
  814     int ok=separatorsDialog.exec();
  815     saveFETDialogGeometry(&separatorsDialog, settingsName);
  816     if(!ok) return false;
  817     
  818     if(separators.size()>1){
  819         assert(separatorsCB!=NULL);
  820         assert(textquoteCB!=NULL);
  821         fieldSeparator=separatorsCB->currentText();
  822         
  823         if(separatorsCB->currentIndex()==NO_SEPARATOR_POS){
  824             assert(fieldSeparator==NO_SEPARATOR_TRANSLATED);
  825             fieldSeparator=QString("no sep"); //must have length >= 2
  826         }
  827         else{
  828             assert(fieldSeparator.size()==1);
  829             //assert(!fieldSeparator.at(0).isLetterOrNumber());
  830         }
  831         
  832         textquote=textquoteCB->currentText();
  833         
  834         if(textquoteCB->currentIndex()==NO_TEXTQUOTE_POS){
  835             assert(textquote==NO_TEXTQUOTE_TRANSLATED);
  836             textquote=QString("no tquote"); //must have length >= 2
  837         }
  838         else{
  839             assert(textquote.size()==1);
  840             //assert(!textquote.at(0).isLetterOrNumber());
  841         }
  842     }
  843     else{
  844         assert(separatorsCB==NULL);
  845         assert(textquoteCB==NULL);
  846         fieldSeparator="";
  847         textquote="";
  848     }
  849 //NEW start
  850             QString tmp;
  851             QString tmpLine=line;
  852             while(!tmpLine.isEmpty()){
  853                 tmp.clear();
  854                 bool foundField=false;
  855                 if(tmpLine.left(1)==textquote){
  856                     tmpLine.remove(0,1);
  857                     while(!foundField && tmpLine.size()>1){
  858                         if(tmpLine.left(1)!=textquote){
  859                             tmp+=tmpLine.left(1);
  860                         } else {
  861                             if(tmpLine.mid(1,1)==fieldSeparator){
  862                                 foundField=true;
  863                                 tmpLine.remove(0,1);
  864                             } else if(tmpLine.mid(1,1)==textquote){
  865                                 tmp+=textquote;
  866                                 tmpLine.remove(0,1);
  867                             } else {
  868                                 QMessageBox::critical(newParent, tr("FET warning"), Import::tr("Missing field separator or text quote in first line. Import might be incorrect.")+"\n");
  869                             }
  870                         }
  871                         tmpLine.remove(0,1);
  872                     }
  873                     if(!foundField && tmpLine.size()==1){
  874                         if(tmpLine.left(1)==textquote){
  875                             tmpLine.remove(0,1);
  876                         } else {
  877                             QMessageBox::critical(newParent, tr("FET warning"), Import::tr("Missing closing text quote in first line. Import might be incorrect.")+"\n");
  878                             tmp+=tmpLine.left(1);
  879                             tmpLine.remove(0,1);
  880                         }
  881                         
  882                     }
  883                 } else {
  884                     while(!foundField && !tmpLine.isEmpty()){
  885                         if(tmpLine.left(1)!=fieldSeparator)
  886                             tmp+=tmpLine.left(1);
  887                         else
  888                             foundField=true;
  889                         tmpLine.remove(0,1);
  890                     }
  891                 }
  892                 fields << tmp;
  893                 if(foundField && tmpLine.isEmpty())
  894                     fields << "";
  895             }
  896 //NEW end
  897 
  898 /* OLD
  899     if(separators.size()>1){
  900         fieldSeparator=separatorsCB->currentText();
  901         fields=line.split(fieldSeparator);
  902     } else {
  903         fieldSeparator=separators.takeFirst();
  904         fields<<line;
  905     }
  906 OLD */
  907 
  908     if(firstLineRadio1->isChecked())
  909         head=true;
  910     else head=false;
  911     return true;
  912 }
  913 
  914 int Import::readFields(QWidget* parent){
  915     QSet<QString> checkSet;
  916     QString check;
  917     numberOfFields=fields.size();
  918     assert(numberOfFields>0);
  919     for(int i=0; i<NUMBER_OF_FIELDS; i++){
  920         assert(fieldNumber[i]<=numberOfFields);
  921         assert(fieldNumber[i]>=DO_NOT_IMPORT);
  922     }
  923 
  924     QFile file(fileName);
  925     if(fileName.isEmpty()){
  926         QMessageBox::warning(parent, tr("FET warning"), tr("Empty filename."));
  927         return false;
  928     }
  929     if(!file.open(QIODevice::ReadOnly)){
  930         QMessageBox::warning(parent, tr("Error! Can't open file."), fileName);
  931         return false;
  932     }
  933     QTextStream in(&file);
  934 #if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
  935     in.setEncoding(QStringConverter::Utf8);
  936 #else
  937     in.setCodec("UTF-8");
  938 #endif
  939 
  940     qint64 size=file.size();
  941     QProgressDialog* _progress=new QProgressDialog(parent);
  942     QProgressDialog& progress=(*_progress);
  943     progress.setWindowTitle(tr("Importing", "Title of a progress dialog"));
  944     progress.setLabelText(tr("Loading file"));
  945     progress.setModal(true);
  946     progress.setRange(0, qMax(size, qint64(1)));
  947     //cout<<"progress in readFields starts"<<endl;
  948     qint64 crt=0;
  949 
  950     QStringList fields;
  951     QString itemOfField[NUMBER_OF_FIELDS];
  952     int lineNumber=0;
  953     while(!in.atEnd()){
  954         progress.setValue(crt);
  955         QString line = in.readLine();
  956         lineNumber++;
  957         crt+=line.length();
  958         if(progress.wasCanceled()){
  959             progress.setValue(size);
  960             QMessageBox::warning(parent, "FET", Import::tr("Loading canceled by user."));
  961             file.close();
  962             return false;
  963         }
  964         bool ok=true;
  965         if(!(lineNumber==1&&head)){
  966             fields.clear();
  967             QString tmp;
  968             QString tmpLine=line;
  969             while(!tmpLine.isEmpty()){
  970                 tmp.clear();
  971                 bool foundField=false;
  972                 if(tmpLine.left(1)==textquote){
  973                     tmpLine.remove(0,1);
  974                     while(!foundField && tmpLine.size()>1){
  975                         if(tmpLine.left(1)!=textquote){
  976                             tmp+=tmpLine.left(1);
  977                         } else {
  978                             if(tmpLine.mid(1,1)==fieldSeparator){
  979                                 foundField=true;
  980                                 tmpLine.remove(0,1);
  981                             } else if(tmpLine.mid(1,1)==textquote){
  982                                 tmp+=textquote;
  983                                 tmpLine.remove(0,1);
  984                             } else
  985                                 warnText+=Import::tr("Warning: FET expected field separator or text separator in line %1. Import might be incorrect.").arg(lineNumber)+"\n";
  986                         }
  987                         tmpLine.remove(0,1);
  988                     }
  989                     if(!foundField && tmpLine.size()==1){
  990                         if(tmpLine.left(1)==textquote){
  991                             tmpLine.remove(0,1);
  992                         } else {
  993                             warnText+=Import::tr("Warning: FET expected closing text separator in line %1. Import might be incorrect.").arg(lineNumber)+"\n";
  994                             tmp+=tmpLine.left(1);
  995                             tmpLine.remove(0,1);
  996                         }
  997                         
  998                     }
  999                 } else {
 1000                     while(!foundField && !tmpLine.isEmpty()){
 1001                         if(tmpLine.left(1)!=fieldSeparator)
 1002                             tmp+=tmpLine.left(1);
 1003                         else
 1004                             foundField=true;
 1005                         tmpLine.remove(0,1);
 1006                     }
 1007                 }
 1008                 fields << tmp;
 1009                 if(foundField && tmpLine.isEmpty())
 1010                     fields << "";
 1011             }
 1012 /*
 1013             if(separator.size()==1){
 1014                 fields = line.split(separator);
 1015             } else
 1016                 fields << line;
 1017 */
 1018             if(numberOfFields!=fields.size()){
 1019                 warnText+=Import::tr("Skipped line %1: FET expected %2 fields but found %3 fields.").arg(lineNumber).arg(numberOfFields).arg(fields.size())+"\n";
 1020                 ok=false;
 1021             } else {
 1022                 for(int i=0; i<NUMBER_OF_FIELDS; i++){
 1023                     if(fieldNumber[i]>=0){
 1024                         itemOfField[i].clear();
 1025                         itemOfField[i] = fields[fieldNumber[i]];
 1026                         if(itemOfField[i].isEmpty()){
 1027                             if(i==FIELD_YEAR_NAME || i==FIELD_TEACHER_NAME || i==FIELD_SUBJECT_NAME){
 1028                                 warnText+=Import::tr("Skipped line %1: Field '%2' is empty.").arg(lineNumber).arg(fieldName[i])+"\n";
 1029                                 ok=false;
 1030                             }
 1031                             if(i==FIELD_YEAR_NUMBER_OF_STUDENTS || i==FIELD_GROUP_NUMBER_OF_STUDENTS || i==FIELD_SUBGROUP_NUMBER_OF_STUDENTS){
 1032                                 itemOfField[i]="0";
 1033                             }
 1034                             //if(i==FIELD_SUBGROUP_NAME) is OK
 1035                             //if(i==FIELD_ACTIVITY_TAG_NAME) is OK
 1036                             //if(i==FIELD_ROOM_NAME) is OK
 1037                             if(i==FIELD_ROOM_CAPACITY){
 1038                                 itemOfField[i]=fieldDefaultItem[i];
 1039                             }
 1040                             if(i==FIELD_MIN_DAYS){
 1041                                 itemOfField[i]="0";
 1042                             }
 1043                             if(i==FIELD_MIN_DAYS_WEIGHT){
 1044                                 if(itemOfField[FIELD_MIN_DAYS].isEmpty()){
 1045                                     ok=false;
 1046                                     warnText+=Import::tr("Skipped line %1: Field '%2' is empty.").arg(lineNumber).arg(fieldName[FIELD_MIN_DAYS])+"\n";
 1047                                 } else
 1048                                     itemOfField[i]="95";
 1049                             }
 1050                             if(i==FIELD_MIN_DAYS_CONSECUTIVE){
 1051                                 if(itemOfField[FIELD_MIN_DAYS].isEmpty()){
 1052                                     ok=false;
 1053                                     warnText+=Import::tr("Skipped line %1: Field '%2' is empty.").arg(lineNumber).arg(fieldName[FIELD_MIN_DAYS])+"\n";
 1054                                 } else
 1055                                     itemOfField[i]="N";
 1056                             }
 1057                         }
 1058                         if(ok && i==FIELD_SUBGROUP_NAME && !itemOfField[FIELD_SUBGROUP_NAME].isEmpty() && itemOfField[FIELD_GROUP_NAME].isEmpty()){
 1059                             warnText+=Import::tr("Skipped line %1: Field '%2' is empty.").arg(lineNumber).arg(fieldName[FIELD_GROUP_NAME])+"\n";
 1060                             ok=false;
 1061                         }
 1062                         if(ok && i==FIELD_SPLIT_DURATION){
 1063                             if(itemOfField[FIELD_SPLIT_DURATION].isEmpty()){
 1064                                 if(!itemOfField[FIELD_TOTAL_DURATION].isEmpty()){
 1065                                     int totalInt=itemOfField[FIELD_TOTAL_DURATION].toInt(&ok, 10);
 1066                                     if(ok && totalInt>=1){
 1067                                         if(totalInt<=MAX_SPLIT_OF_AN_ACTIVITY){
 1068                                             QString tmpString;
 1069                                             for(int n=0; n<totalInt; n++){
 1070                                                 if(n!=0)
 1071                                                     tmpString+="+";
 1072                                                 tmpString+="1";
 1073                                             }
 1074                                             itemOfField[FIELD_SPLIT_DURATION]=tmpString;
 1075                                         } else {
 1076                                             warnText+=Import::tr("Skipped line %1: Field '%2' produces too many subactivities.").arg(lineNumber).arg(fieldName[FIELD_TOTAL_DURATION])+"\n";
 1077                                             ok=false;
 1078                                         }
 1079                                     } else {
 1080                                         warnText+=Import::tr("Skipped line %1: Field '%2' contain incorrect data.").arg(lineNumber).arg(fieldName[FIELD_TOTAL_DURATION])+"\n";
 1081                                         ok=false;
 1082                                     }
 1083                                 } else {
 1084                                     warnText+=Import::tr("Skipped line %1: Field '%2' is empty.").arg(lineNumber).arg(fieldName[i])+"\n";
 1085                                     ok=false;
 1086                                 }
 1087                             } else {
 1088 #if QT_VERSION >= QT_VERSION_CHECK(5,15,0)
 1089                                 QStringList splitList=itemOfField[FIELD_SPLIT_DURATION].split("+", Qt::SkipEmptyParts);
 1090 #else
 1091                                 QStringList splitList=itemOfField[FIELD_SPLIT_DURATION].split("+", QString::SkipEmptyParts);
 1092 #endif
 1093                                 if(splitList.size()<MAX_SPLIT_OF_AN_ACTIVITY){
 1094                                     int tmpInt=0;
 1095                                     for(const QString& split : qAsConst(splitList)){
 1096                                         tmpInt+=split.toInt(&ok, 10);
 1097                                         if(!ok)
 1098                                             warnText+=Import::tr("Skipped line %1: Field '%2' doesn't contain an integer value.").arg(lineNumber).arg(fieldName[FIELD_SPLIT_DURATION])+"\n";
 1099                                     }
 1100                                     if(itemOfField[FIELD_TOTAL_DURATION].isEmpty()){
 1101                                         itemOfField[FIELD_TOTAL_DURATION]=CustomFETString::number(tmpInt);
 1102                                     } else {
 1103                                         int totalInt=itemOfField[FIELD_TOTAL_DURATION].toInt(&ok, 10);
 1104                                         if(totalInt!=tmpInt){
 1105                                             warnText+=Import::tr("Skipped line %1: Fields '%2' and '%3' do not have the same value.").arg(lineNumber).arg(fieldName[i]).arg(fieldName[FIELD_TOTAL_DURATION])+"\n";
 1106                                             ok=false;
 1107                                         }
 1108                                     }
 1109                                 } else {
 1110                                     warnText+=Import::tr("Skipped line %1: Field '%2' contains too many subactivities.").arg(lineNumber).arg(fieldName[i])+"\n";
 1111                                     ok=false;
 1112                                 }
 1113                             }
 1114                         }
 1115                         if(ok && !itemOfField[FIELD_BUILDING_NAME].isEmpty() && itemOfField[FIELD_ROOM_NAME].isEmpty() && i==FIELD_ROOM_NAME){
 1116                             warnText+=Import::tr("Warning in line %1: Field with building name doesn't relate to a room").arg(lineNumber)+"\n";
 1117                         }
 1118                         if(ok && (i==FIELD_YEAR_NUMBER_OF_STUDENTS || i==FIELD_GROUP_NUMBER_OF_STUDENTS || i==FIELD_SUBGROUP_NUMBER_OF_STUDENTS || i==FIELD_ROOM_CAPACITY || i==FIELD_TOTAL_DURATION || i==FIELD_MIN_DAYS)){
 1119                             if(!itemOfField[i].isEmpty()){
 1120                                 int value=itemOfField[i].toInt(&ok, 10);
 1121                                 if(!ok)
 1122                                     warnText+=Import::tr("Skipped line %1: Field '%2' doesn't contain an integer value.").arg(lineNumber).arg(fieldName[i])+"\n";
 1123                                 else {
 1124                                     if(value<0){
 1125                                         warnText+=Import::tr("Skipped line %1: Field '%2' contains an invalid integer value.").arg(lineNumber).arg(fieldName[i])+"\n";
 1126                                         ok=false;
 1127                                     }
 1128                                 }
 1129                             } else if(i==FIELD_TOTAL_DURATION){
 1130                                  assert(true);
 1131                             }else{
 1132                                 ok=false;
 1133                                 warnText+=Import::tr("Skipped line %1: Field '%2' doesn't contain an integer value.").arg(lineNumber).arg(fieldName[i])+"\n";
 1134                                 //because of bug reported by murad on 25 May 2010, crash when importing rooms, if capacity is empty
 1135                                 //assert(false);
 1136                             }
 1137                         }
 1138                         if(ok && i==FIELD_MIN_DAYS_WEIGHT){
 1139 //                          double weight=itemOfField[i].toDouble(&ok);
 1140                             double weight=customFETStrToDouble(itemOfField[i], &ok);
 1141                             if(!ok)
 1142                                 warnText+=Import::tr("Skipped line %1: Field '%2' doesn't contain a number (double) value.").arg(lineNumber).arg(fieldName[i])+"\n";
 1143                             else {
 1144                                 if(weight<0.0 || weight>100.0){
 1145                                     warnText+=Import::tr("Skipped line %1: Field '%2' contains an invalid number (double) value.").arg(lineNumber).arg(fieldName[i])+"\n";
 1146                                     ok=false;
 1147                                 }
 1148                             }
 1149                         }
 1150                         if(ok && i==FIELD_MIN_DAYS_CONSECUTIVE){
 1151                             QString tmpString;
 1152                             tmpString=itemOfField[i];
 1153                             tmpString=tmpString.toUpper();
 1154                             if(tmpString=="Y" || tmpString=="YES" ||  tmpString=="T" || tmpString=="TRUE" || tmpString=="1")
 1155                                 itemOfField[i]="yes";
 1156                             else if(tmpString=="N" || tmpString=="NO" || tmpString=="F" || tmpString=="FALSE" || tmpString=="0")
 1157                                 itemOfField[i]="no";
 1158                             else
 1159                                 ok=false;
 1160                             if(!ok)
 1161                                 warnText+=Import::tr("Skipped line %1: Field '%2' contains an unknown value.").arg(lineNumber).arg(fieldName[i])+"\n";
 1162                         }
 1163                     } else if(fieldNumber[i]==IMPORT_DEFAULT_ITEM){
 1164                         itemOfField[i].clear();
 1165                         itemOfField[i] = fieldDefaultItem[i];
 1166                         //Removed by Liviu - we may have empty default fields
 1167                         //assert(!fieldDefaultItem[i].isEmpty());
 1168                     }
 1169                 }
 1170             }
 1171             if(ok){
 1172                 check.clear();
 1173                 for(int i=0; i<NUMBER_OF_FIELDS; i++){
 1174                     check+=itemOfField[i]+" ";
 1175                 }
 1176                 if(checkSet.contains(check)){
 1177                     if(fieldNumber[FIELD_SPLIT_DURATION]!=DO_NOT_IMPORT||fieldNumber[FIELD_TOTAL_DURATION]!=DO_NOT_IMPORT){
 1178                         warnText+=Import::tr("Note about line %1: Data was already in a previous line. So this data will be imported once again.").arg(lineNumber)+"\n";
 1179                     } else {
 1180                         warnText+=Import::tr("Skipped line %1: Data was already in a previous line.").arg(lineNumber)+"\n";
 1181                         ok=false;
 1182                     }
 1183                 } else
 1184                     checkSet<<check;
 1185             }
 1186             if(ok){
 1187                 //QString tmp;
 1188                 //tmp=tr("%1").arg(lineNumber);
 1189                 //itemOfField[FIELD_LINE_NUMBER]=tmp;
 1190                 itemOfField[FIELD_LINE_NUMBER]=CustomFETString::number(lineNumber);
 1191                 for(int i=0; i<NUMBER_OF_FIELDS; i++){
 1192                     if(fieldNumber[i]!=DO_NOT_IMPORT)
 1193                         fieldList[i]<<itemOfField[i];
 1194                 }
 1195             } else
 1196                 warnText+="   "+Import::tr("Line %1 is: %2").arg(lineNumber).arg(line)+"\n";
 1197         }
 1198     }
 1199     progress.setValue(qMax(size, qint64(1)));
 1200     //cout<<"progress in readFields ends"<<endl;
 1201     int max=0;
 1202     for(int i=0; i<NUMBER_OF_FIELDS; i++){
 1203         if(max==0)
 1204             max=fieldList[i].size();
 1205         if(fieldNumber[i]>DO_NOT_IMPORT){
 1206             assert(fieldList[i].size()==max);
 1207         }
 1208         else
 1209             assert(fieldList[i].isEmpty());
 1210     }
 1211     file.close();
 1212     return true;
 1213 }
 1214 
 1215 int Import::showFieldsAndWarnings(QWidget* parent, QDialog* &newParent){
 1216     newParent=((QDialog*)parent);
 1217 
 1218     int ok=true;
 1219 
 1220     int max=0;
 1221     for(int i=0; i<NUMBER_OF_FIELDS; i++){
 1222         if(fieldNumber[i]>DO_NOT_IMPORT){
 1223             if(max==0)
 1224                 max=fieldList[i].size();
 1225             assert(fieldList[i].size()==max);
 1226         }
 1227         else{
 1228             if(i!=FIELD_TEACHER_NAME){      //needed for activities!
 1229                 //assert(fieldList[i].isEmpty());
 1230                 //because of bug reported 17.03.2008. Please add again?! compare add activities function
 1231             }
 1232         }
 1233     }
 1234     // Start Dialog
 1235     newParent=new QDialog(parent);
 1236     QDialog& addItemsDialog=(*newParent);
 1237     addItemsDialog.setWindowTitle(Import::tr("FET import %1 question").arg(importThing));
 1238     QVBoxLayout* addItemsMainLayout=new QVBoxLayout(&addItemsDialog);
 1239 
 1240     //Start Warnings
 1241     QHBoxLayout* headWarnings=new QHBoxLayout();
 1242     QLabel* headWarningsText=new QLabel();
 1243 
 1244     int tmp=fileName.lastIndexOf(FILE_SEP);
 1245     tmp=fileName.size()-tmp-1;
 1246     QString shortFileName=fileName.right(tmp);
 1247     if(!warnText.isEmpty())
 1248         headWarningsText->setText(Import::tr("There are several problems in file\n%1").arg(shortFileName));
 1249     else
 1250         headWarningsText->setText(Import::tr("There are no problems in file\n%1").arg(shortFileName));
 1251 
 1252 //TODO
 1253 /*
 1254 tr("There are no problems in file")
 1255 +
 1256 "\n"
 1257 +
 1258 FILE_STRIPPED_NAME
 1259 */
 1260 
 1261     headWarnings->addWidget(headWarningsText);
 1262     headWarnings->addStretch();
 1263 
 1264     QPlainTextEdit* textOfWarnings=new QPlainTextEdit();
 1265     textOfWarnings->setMinimumWidth(500);           //width
 1266     textOfWarnings->setReadOnly(true);
 1267     textOfWarnings->setWordWrapMode(QTextOption::NoWrap);
 1268     textOfWarnings->setPlainText(warnText);
 1269 
 1270     //Start data table
 1271     QLabel* headTableText=new QLabel();
 1272     if(max!=0)
 1273         headTableText->setText(Import::tr("Following data found in the file:"));
 1274     else
 1275         headTableText->setText(Import::tr("There is no usable data in the file."));
 1276 
 1277     QTableWidget* fieldsTable= new QTableWidget;
 1278     
 1279     //fieldsTable->setUpdatesEnabled(false);
 1280     
 1281     fieldsTable->setRowCount(max);
 1282     QStringList fieldsTabelLabel;
 1283 
 1284     int columns=0;
 1285     for(int i=0; i<NUMBER_OF_FIELDS; i++){
 1286         if(fieldNumber[i]>DO_NOT_IMPORT){
 1287             fieldsTabelLabel<<tr("%1").arg(fieldName[i]);
 1288             columns++;
 1289         }
 1290     }
 1291     fieldsTable->setColumnCount(columns);
 1292     fieldsTable->setHorizontalHeaderLabels(fieldsTabelLabel);
 1293     for(int i=0; i<max; i++){
 1294         int column=0;
 1295         for(int f=0; f<NUMBER_OF_FIELDS; f++){
 1296             if(fieldNumber[f]>DO_NOT_IMPORT){
 1297                 QTableWidgetItem* newItem=new QTableWidgetItem(fieldList[f][i]);
 1298                 newItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
 1299                 fieldsTable->setItem(i, column, newItem);
 1300                 column++;
 1301             }
 1302         }
 1303     }
 1304     fieldsTable->resizeColumnsToContents();
 1305     //fieldsTable->resizeRowsToContents(); This takes too long for many rows, and it is also useless.
 1306 
 1307     //fieldsTable->setUpdatesEnabled(true);
 1308 
 1309     //Start current data warning
 1310     QVBoxLayout* dataWarningBox=new QVBoxLayout();
 1311     QLabel* dataWarningText=new QLabel();
 1312     /*if(dataWarning.size()==1)
 1313         dataWarningText->setText(Import::tr("FET noticed 1 warning with the current data."));
 1314     else*/
 1315     dataWarningText->setText(Import::tr("FET noticed %1 warnings with the current data.").arg(dataWarning.size()));
 1316     dataWarningBox->addWidget(dataWarningText);
 1317 
 1318     QListWidget* dataWarningItems=new QListWidget();
 1319     dataWarningItems->addItems(dataWarning);
 1320     if(dataWarning.size()>0)
 1321         dataWarningBox->addWidget(dataWarningItems);
 1322     else
 1323         delete dataWarningItems;
 1324 
 1325     //Start Buttons
 1326     QPushButton* pb1=new QPushButton(tr("&Import"));
 1327     QPushButton* pb2=new QPushButton(tr("&Cancel"));
 1328 
 1329     //TODO: why doesn't work this?
 1330     //if((dataWarning.size()>0&&dataWarning.size()==max)||!warnText.isEmpty())
 1331     //  pb2->setDefault(true);
 1332     //else
 1333     //   pb1->setDefault(true);
 1334     //   pb1->setFocus();
 1335         // pb1->setAutoDefault(true);
 1336 
 1337     QHBoxLayout* hl=new QHBoxLayout();
 1338     hl->addStretch();
 1339     hl->addWidget(pb1);
 1340     hl->addWidget(pb2);
 1341 
 1342     //Start adding all into main layout
 1343     addItemsMainLayout->addLayout(headWarnings);
 1344     if(!warnText.isEmpty())
 1345         addItemsMainLayout->addWidget(textOfWarnings);
 1346     else
 1347         delete textOfWarnings;
 1348     addItemsMainLayout->addWidget(headTableText);
 1349     if(max!=0)
 1350         addItemsMainLayout->addWidget(fieldsTable);
 1351     else
 1352         delete fieldsTable;
 1353     addItemsMainLayout->addLayout(dataWarningBox);
 1354     addItemsMainLayout->addLayout(hl);
 1355 
 1356     QObject::connect(pb1, SIGNAL(clicked()), &addItemsDialog, SLOT(accept()));
 1357     QObject::connect(pb2, SIGNAL(clicked()), &addItemsDialog, SLOT(reject()));
 1358 
 1359     //pb1->setDefault(true);
 1360     
 1361     int w=chooseWidth(addItemsDialog.sizeHint().width());
 1362     int h=chooseHeight(addItemsDialog.sizeHint().height());
 1363     addItemsDialog.resize(w,h);
 1364     
 1365     QString settingsName;
 1366     if(importThing==Import::tr("activity tags"))
 1367         settingsName=QString("ImportActivityTagsShowFieldsAndWarningsDialog");
 1368     else if(importThing==Import::tr("buildings and rooms"))
 1369         settingsName=QString("ImportBuildingsRoomsShowFieldsAndWarningsDialog");
 1370     else if(importThing==Import::tr("teachers"))
 1371         settingsName=QString("ImportTeachersShowFieldsAndWarningsDialog");
 1372     else if(importThing==Import::tr("subjects"))
 1373         settingsName=QString("ImportSubjectsShowFieldsAndWarningsDialog");
 1374     else if(importThing==Import::tr("years, groups and subgroups"))
 1375         settingsName=QString("ImportYearsGroupsSubgroupsShowFieldsAndWarningsDialog");
 1376     else if(importThing==Import::tr("activities"))
 1377         settingsName=QString("ImportActivitiesShowFieldsAndWarningsDialog");
 1378     
 1379     pb1->setDefault(true);
 1380     pb1->setFocus();
 1381 
 1382     centerWidgetOnScreen(&addItemsDialog);
 1383     restoreFETDialogGeometry(&addItemsDialog, settingsName);
 1384 
 1385     ok=addItemsDialog.exec();
 1386     saveFETDialogGeometry(&addItemsDialog, settingsName);
 1387     
 1388     return ok;
 1389 }
 1390 
 1391 void Import::importCSVActivityTags(QWidget* parent){
 1392     prearrangement();
 1393     fieldNumber[FIELD_ACTIVITY_TAG_NAME]=IMPORT_DEFAULT_ITEM;
 1394     int ok;
 1395 
 1396     QDialog* newParent;
 1397     ok = getFileSeparatorFieldsAndHead(parent, newParent);
 1398     //DON'T ADD THIS! newParent->deleteLater();
 1399     if(!ok) return;
 1400 
 1401     if(fieldNumber[FIELD_ACTIVITY_TAG_NAME]==IMPORT_DEFAULT_ITEM){
 1402         QDialog* newParent2=new ChooseFieldsDialog(newParent);
 1403         const QString settingsName=QString("ImportActivityTagsChooseFieldsDialog");
 1404         //DON'T ADD THIS! newParent2->deleteLater();
 1405         newParent=newParent2;
 1406         ChooseFieldsDialog& cfd=(*((ChooseFieldsDialog*)newParent));
 1407         int w= chooseWidth(cfd.sizeHint().width());
 1408         int h= chooseHeight(cfd.sizeHint().height());
 1409         cfd.resize(w,h);
 1410         centerWidgetOnScreen(&cfd);
 1411         restoreFETDialogGeometry(&cfd, settingsName);
 1412         
 1413         ok=cfd.exec();
 1414         saveFETDialogGeometry(&cfd, settingsName);
 1415         if(!ok) return;
 1416     }
 1417 
 1418     ok = readFields(newParent);
 1419     if(!ok) return;
 1420 
 1421     //check empty fields (start)
 1422     for(int i=0; i<fieldList[FIELD_ACTIVITY_TAG_NAME].size(); i++){
 1423         if(fieldList[FIELD_ACTIVITY_TAG_NAME][i].isEmpty())
 1424             warnText+=Import::tr("Skipped line %1: Field '%2' is empty.").arg(fieldList[FIELD_LINE_NUMBER][i]).arg(fieldName[FIELD_ACTIVITY_TAG_NAME])+"\n";
 1425     }
 1426     //check empty fields (end)
 1427 
 1428     //check if already in memory (start)
 1429 #if QT_VERSION >= QT_VERSION_CHECK(5,14,0)
 1430     QSet<QString> tmpSet=QSet<QString>(fieldList[FIELD_ACTIVITY_TAG_NAME].begin(), fieldList[FIELD_ACTIVITY_TAG_NAME].end());
 1431 #else
 1432     QSet<QString> tmpSet=fieldList[FIELD_ACTIVITY_TAG_NAME].toSet();
 1433 #endif
 1434     for(int i=0; i<gt.rules.activityTagsList.size(); i++){
 1435         ActivityTag* a=gt.rules.activityTagsList[i];
 1436         if(tmpSet.contains(a->name))
 1437             dataWarning<<Import::tr("%1 is already in FET data.").arg(a->name);
 1438     }
 1439     //check if already in memory (end)
 1440     QDialog* newParent2;
 1441     ok = showFieldsAndWarnings(newParent, newParent2);
 1442     //DON'T ADD THIS! newParent2->deleteLater();
 1443     newParent=newParent2;
 1444     if(!ok) return;
 1445 
 1446     //add activity tags (start) - similar to teachersform.cpp by Liviu modified by Volker
 1447     tmpSet.clear();
 1448     for(ActivityTag* at : qAsConst(gt.rules.activityTagsList))
 1449         tmpSet.insert(at->name);
 1450     int count=0;
 1451     for(int i=0; i<fieldList[FIELD_ACTIVITY_TAG_NAME].size(); i++){
 1452         if(!fieldList[FIELD_ACTIVITY_TAG_NAME][i].isEmpty() && !tmpSet.contains(fieldList[FIELD_ACTIVITY_TAG_NAME][i])){
 1453             tmpSet.insert(fieldList[FIELD_ACTIVITY_TAG_NAME][i]);
 1454             ActivityTag* a=new ActivityTag();
 1455             a->name=fieldList[FIELD_ACTIVITY_TAG_NAME][i];
 1456             if(!gt.rules.addActivityTagFast(a)){
 1457                 delete a;
 1458                 assert(0);
 1459             } else count++;
 1460         }
 1461     }
 1462     QMessageBox::information(newParent, tr("FET information"), Import::tr("%1 activity tags added. Please check activity tags form.").arg(count));
 1463     //add activity tags (end) - similar to teachersform.cpp by Liviu modified by Volker
 1464     int tmp=fileName.lastIndexOf(FILE_SEP);
 1465     IMPORT_DIRECTORY=fileName.left(tmp);
 1466     //gt.rules.internalStructureComputed=false;
 1467 }
 1468 
 1469 void Import::importCSVRoomsAndBuildings(QWidget* parent){
 1470     prearrangement();
 1471     fieldNumber[FIELD_ROOM_NAME]=IMPORT_DEFAULT_ITEM;
 1472     fieldNumber[FIELD_ROOM_CAPACITY]=IMPORT_DEFAULT_ITEM;
 1473     fieldNumber[FIELD_BUILDING_NAME]=IMPORT_DEFAULT_ITEM;
 1474     int ok;
 1475 
 1476     QDialog* newParent;
 1477     ok = getFileSeparatorFieldsAndHead(parent, newParent);
 1478     //DON'T ADD THIS! newParent->deleteLater();
 1479     if(!ok) return;
 1480 
 1481     if(fieldNumber[FIELD_ROOM_NAME]==IMPORT_DEFAULT_ITEM){
 1482         QDialog* newParent2=new ChooseFieldsDialog(newParent);
 1483         const QString settingsName=QString("ImportRoomsBuildingsChooseFieldsDialog");
 1484         //DON'T ADD THIS! newParent2->deleteLater();
 1485         newParent=newParent2;
 1486         ChooseFieldsDialog& cfd=(*((ChooseFieldsDialog*)newParent));
 1487         int w= chooseWidth(cfd.sizeHint().width());
 1488         int h= chooseHeight(cfd.sizeHint().height());
 1489         cfd.resize(w,h);
 1490         centerWidgetOnScreen(&cfd);
 1491         restoreFETDialogGeometry(&cfd, settingsName);
 1492 
 1493         ok=cfd.exec();
 1494         saveFETDialogGeometry(&cfd, settingsName);
 1495     }
 1496 
 1497     if(!ok) return;
 1498 
 1499     ok = readFields(newParent);
 1500     if(!ok) return;
 1501 
 1502     QSet<QString> duplicatesCheck;
 1503     //check duplicates of rooms in csv
 1504     if(fieldNumber[FIELD_ROOM_NAME]!=DO_NOT_IMPORT)
 1505         for(int i=0; i<fieldList[FIELD_ROOM_NAME].size(); i++){
 1506             if(duplicatesCheck.contains(fieldList[FIELD_ROOM_NAME][i]))
 1507                 warnText+=Import::tr("Skipped line %1: Field '%2' is already in a previous line.").arg(fieldList[FIELD_LINE_NUMBER][i]).arg(fieldName[FIELD_ROOM_NAME])+"\n";
 1508             else
 1509                 duplicatesCheck<<fieldList[FIELD_ROOM_NAME][i];
 1510         }
 1511     duplicatesCheck.clear();
 1512     //check duplicates of buildings in csv. only if no room is imported.
 1513     if(fieldNumber[FIELD_ROOM_NAME]==DO_NOT_IMPORT&&fieldNumber[FIELD_BUILDING_NAME]!=DO_NOT_IMPORT)
 1514         for(int i=0; i<fieldList[FIELD_BUILDING_NAME].size(); i++){
 1515             if(duplicatesCheck.contains(fieldList[FIELD_BUILDING_NAME][i]))
 1516                 warnText+=Import::tr("Skipped line %1: Field '%2' is already in a previous line.").arg(fieldList[FIELD_LINE_NUMBER][i]).arg(fieldName[FIELD_BUILDING_NAME])+"\n";
 1517             else
 1518                 duplicatesCheck<<fieldList[FIELD_BUILDING_NAME][i];
 1519         }
 1520     duplicatesCheck.clear();
 1521     //check empty rooms (start)
 1522     if(fieldNumber[FIELD_ROOM_NAME]!=DO_NOT_IMPORT)
 1523         for(int i=0; i<fieldList[FIELD_ROOM_NAME].size(); i++)
 1524             if(fieldList[FIELD_ROOM_NAME][i].isEmpty())
 1525                 warnText+=Import::tr("Skipped line %1: Field '%2' is empty.").arg(fieldList[FIELD_LINE_NUMBER][i]).arg(fieldName[FIELD_ROOM_NAME])+"\n";
 1526     //check empty rooms (end)
 1527     //check empty buildings (start)
 1528     if((fieldNumber[FIELD_ROOM_NAME]==DO_NOT_IMPORT||fieldNumber[FIELD_ROOM_NAME]==IMPORT_DEFAULT_ITEM)&&fieldNumber[FIELD_BUILDING_NAME]!=DO_NOT_IMPORT)
 1529         for(int i=0; i<fieldList[FIELD_BUILDING_NAME].size(); i++)
 1530             if(fieldList[FIELD_BUILDING_NAME][i].isEmpty())
 1531                 warnText+=Import::tr("Skipped line %1: Field '%2' is empty.").arg(fieldList[FIELD_LINE_NUMBER][i]).arg(fieldName[FIELD_BUILDING_NAME])+"\n";
 1532     //check empty buildings (end)
 1533 
 1534     //check if rooms are already in memory (start)
 1535 #if QT_VERSION >= QT_VERSION_CHECK(5,14,0)
 1536     QSet<QString> tmpSet=QSet<QString>(fieldList[FIELD_ROOM_NAME].begin(), fieldList[FIELD_ROOM_NAME].end());
 1537 #else
 1538     QSet<QString> tmpSet=fieldList[FIELD_ROOM_NAME].toSet();
 1539 #endif
 1540     for(int i=0; i<gt.rules.roomsList.size(); i++){
 1541         Room* r=gt.rules.roomsList[i];
 1542         if(tmpSet.contains(r->name))
 1543             dataWarning<<Import::tr("%1 is already in FET data.").arg(r->name);
 1544     }
 1545     //check if rooms are already in memory (end)
 1546 
 1547     //check if buildings are already in memory (start)
 1548     if(fieldNumber[FIELD_ROOM_NAME]<0){
 1549 #if QT_VERSION >= QT_VERSION_CHECK(5,14,0)
 1550         tmpSet=QSet<QString>(fieldList[FIELD_BUILDING_NAME].begin(), fieldList[FIELD_BUILDING_NAME].end());
 1551 #else
 1552         tmpSet=fieldList[FIELD_BUILDING_NAME].toSet();
 1553 #endif
 1554         for(int i=0; i<gt.rules.buildingsList.size(); i++){
 1555             Building* b=gt.rules.buildingsList[i];
 1556             if(tmpSet.contains(b->name))
 1557                 dataWarning<<Import::tr("%1 is already in FET data.").arg(b->name);
 1558         }
 1559     }
 1560     //check if buildings are already in memory (end)
 1561 
 1562     QDialog* newParent2;
 1563     ok = showFieldsAndWarnings(newParent, newParent2);
 1564     //DON'T ADD THIS! newParent2->deleteLater();
 1565     newParent=newParent2;
 1566     if(!ok) return;
 1567 
 1568     //add buildings (start) - similar to teachersform.cpp by Liviu modified by Volker
 1569     tmpSet.clear();
 1570     for(Building* bu : qAsConst(gt.rules.buildingsList))
 1571         tmpSet.insert(bu->name);
 1572     int count=0;
 1573     for(int i=0; i<fieldList[FIELD_BUILDING_NAME].size(); i++){
 1574         if(!fieldList[FIELD_BUILDING_NAME][i].isEmpty() && !tmpSet.contains(fieldList[FIELD_BUILDING_NAME][i])){
 1575             tmpSet.insert(fieldList[FIELD_BUILDING_NAME][i]);
 1576             Building* b=new Building();
 1577             b->name=fieldList[FIELD_BUILDING_NAME][i];
 1578             if(!gt.rules.addBuildingFast(b)){
 1579                 delete b;
 1580                 assert(0);
 1581             } else count++;
 1582         }
 1583     }
 1584     //add buildings (end) - similar to teachersform.cpp by Liviu modified by Volker
 1585 
 1586     //add rooms (start) - similar to teachersform.cpp by Liviu modified by Volker
 1587     tmpSet.clear();
 1588     for(Room* rm : qAsConst(gt.rules.roomsList))
 1589         tmpSet.insert(rm->name);
 1590     int countroom=0;
 1591     for(int i=0; i<fieldList[FIELD_ROOM_NAME].size(); i++){
 1592         if(!fieldList[FIELD_ROOM_NAME][i].isEmpty() && !tmpSet.contains(fieldList[FIELD_ROOM_NAME][i])){
 1593             tmpSet.insert(fieldList[FIELD_ROOM_NAME][i]);
 1594             Room* r=new Room();
 1595             r->name=fieldList[FIELD_ROOM_NAME][i];
 1596             if(fieldNumber[FIELD_BUILDING_NAME]!=DO_NOT_IMPORT)
 1597                 r->building=fieldList[FIELD_BUILDING_NAME][i];
 1598             else
 1599                 r->building="";
 1600             if(fieldNumber[FIELD_ROOM_CAPACITY]!=DO_NOT_IMPORT){
 1601                 QString tmpInt=fieldList[FIELD_ROOM_CAPACITY][i];
 1602                 r->capacity=tmpInt.toInt();
 1603             }
 1604             else
 1605                 assert(0==1);
 1606             if(!gt.rules.addRoomFast(r)){
 1607                 delete r;
 1608                 assert(0);
 1609             } else countroom++;
 1610         }
 1611     }
 1612     //add rooms (end) - similar to teachersform.cpp by Liviu modified by Volker
 1613     QMessageBox::information(newParent, tr("FET information"),
 1614      Import::tr("%1 buildings added. Please check buildings form.").arg(count)+"\n"+tr("%1 rooms added. Please check rooms form.").arg(countroom));
 1615 
 1616     int tmp=fileName.lastIndexOf(FILE_SEP);
 1617     IMPORT_DIRECTORY=fileName.left(tmp);
 1618     //gt.rules.internalStructureComputed=false;
 1619 }
 1620 
 1621 void Import::importCSVSubjects(QWidget* parent){
 1622     prearrangement();
 1623     fieldNumber[FIELD_SUBJECT_NAME]=IMPORT_DEFAULT_ITEM;
 1624     int ok;
 1625 
 1626     QDialog* newParent;
 1627     ok = getFileSeparatorFieldsAndHead(parent, newParent);
 1628     //DON'T ADD THIS! newParent->deleteLater();
 1629     if(!ok) return;
 1630 
 1631     if(fieldNumber[FIELD_SUBJECT_NAME]==IMPORT_DEFAULT_ITEM){
 1632         QDialog* newParent2=new ChooseFieldsDialog(newParent);
 1633         const QString settingsName=QString("ImportSubjectsChooseFieldsDialog");
 1634         //DON'T ADD THIS! newParent2->deleteLater();
 1635         newParent=newParent2;
 1636         ChooseFieldsDialog& cfd=(*((ChooseFieldsDialog*)newParent));
 1637         int w= chooseWidth(cfd.sizeHint().width());
 1638         int h= chooseHeight(cfd.sizeHint().height());
 1639         cfd.resize(w,h);
 1640         centerWidgetOnScreen(&cfd);
 1641         restoreFETDialogGeometry(&cfd, settingsName);
 1642 
 1643         ok=cfd.exec();
 1644         saveFETDialogGeometry(&cfd, settingsName);
 1645     }
 1646 
 1647     if(!ok) return;
 1648 
 1649     ok = readFields(newParent);
 1650     if(!ok) return;
 1651 
 1652     //check empty fields (start)
 1653     for(int i=0; i<fieldList[FIELD_SUBJECT_NAME].size(); i++){
 1654         if(fieldList[FIELD_SUBJECT_NAME][i].isEmpty())
 1655             warnText+=Import::tr("Skipped line %1: Field '%2' is empty.").arg(fieldList[FIELD_LINE_NUMBER][i]).arg(fieldName[FIELD_SUBJECT_NAME])+"\n";
 1656     }
 1657     //check empty fields (end)
 1658 
 1659     //check if already in memory (start)
 1660 #if QT_VERSION >= QT_VERSION_CHECK(5,14,0)
 1661     QSet<QString> tmpSet(fieldList[FIELD_SUBJECT_NAME].begin(), fieldList[FIELD_SUBJECT_NAME].end());
 1662 #else
 1663     QSet<QString> tmpSet=fieldList[FIELD_SUBJECT_NAME].toSet();
 1664 #endif
 1665     for(int i=0; i<gt.rules.subjectsList.size(); i++){
 1666         Subject* s=gt.rules.subjectsList[i];
 1667         if(tmpSet.contains(s->name))
 1668             dataWarning<<Import::tr("%1 is already in FET data.").arg(s->name);
 1669     }
 1670     //check if already in memory (end)
 1671 
 1672     QDialog* newParent2;
 1673     ok = showFieldsAndWarnings(newParent, newParent2);
 1674     //DON'T ADD THIS! newParent2->deleteLater();
 1675     newParent=newParent2;
 1676     if(!ok) return;
 1677 
 1678     //add subjects (start) - similar to teachersform.cpp by Liviu modified by Volker
 1679     tmpSet.clear();
 1680     for(Subject* sbj : qAsConst(gt.rules.subjectsList))
 1681         tmpSet.insert(sbj->name);
 1682     int count=0;
 1683     for(int i=0; i<fieldList[FIELD_SUBJECT_NAME].size(); i++){
 1684         if(!fieldList[FIELD_SUBJECT_NAME][i].isEmpty() && !tmpSet.contains(fieldList[FIELD_SUBJECT_NAME][i])){
 1685             tmpSet.insert(fieldList[FIELD_SUBJECT_NAME][i]);
 1686             Subject* s=new Subject();
 1687             s->name=fieldList[FIELD_SUBJECT_NAME][i];
 1688             if(!gt.rules.addSubjectFast(s)){
 1689                 delete s;
 1690                 assert(0);
 1691             } else count++;
 1692         }
 1693     }
 1694     //add subjects (end) - similar to teachersform.cpp by Liviu modified by Volker
 1695     QMessageBox::information(newParent, tr("FET information"), Import::tr("%1 subjects added. Please check subjects form.").arg(count));
 1696     int tmp=fileName.lastIndexOf(FILE_SEP);
 1697     IMPORT_DIRECTORY=fileName.left(tmp);
 1698     //gt.rules.internalStructureComputed=false;
 1699 }
 1700 
 1701 void Import::importCSVTeachers(QWidget* parent){
 1702     prearrangement();
 1703     fieldNumber[FIELD_TEACHER_NAME]=IMPORT_DEFAULT_ITEM;
 1704     int ok;
 1705 
 1706     QDialog* newParent;
 1707     ok = getFileSeparatorFieldsAndHead(parent, newParent);
 1708     //DON'T ADD THIS! newParent->deleteLater();
 1709     if(!ok) return;
 1710 
 1711     if(fieldNumber[FIELD_TEACHER_NAME]==IMPORT_DEFAULT_ITEM){
 1712         QDialog* newParent2=new ChooseFieldsDialog(newParent);
 1713         const QString settingsName=QString("ImportTeachersChooseFieldsDialog");
 1714         //DON'T ADD THIS! newParent2->deleteLater();
 1715         newParent=newParent2;
 1716         ChooseFieldsDialog& cfd=(*((ChooseFieldsDialog*)newParent));
 1717         int w= chooseWidth(cfd.sizeHint().width());
 1718         int h= chooseHeight(cfd.sizeHint().height());
 1719         cfd.resize(w,h);
 1720         centerWidgetOnScreen(&cfd);
 1721         restoreFETDialogGeometry(&cfd, settingsName);
 1722 
 1723         ok=cfd.exec();
 1724         saveFETDialogGeometry(&cfd, settingsName);
 1725     }
 1726 
 1727     if(!ok) return;
 1728 
 1729     ok = readFields(newParent);
 1730     if(!ok) return;
 1731 
 1732     //check empty fields (start)
 1733     for(int i=0; i<fieldList[FIELD_TEACHER_NAME].size(); i++){
 1734         if(fieldList[FIELD_TEACHER_NAME][i].isEmpty())
 1735             warnText+=Import::tr("Skipped line %1: Field '%2' is empty.").arg(fieldList[FIELD_LINE_NUMBER][i]).arg(fieldName[FIELD_TEACHER_NAME])+"\n";
 1736     }
 1737     //check empty fields (end)
 1738 
 1739     //check if already in memory (start)
 1740 #if QT_VERSION >= QT_VERSION_CHECK(5,14,0)
 1741     QSet<QString> tmpSet(fieldList[FIELD_TEACHER_NAME].begin(), fieldList[FIELD_TEACHER_NAME].end());
 1742 #else
 1743     QSet<QString> tmpSet=fieldList[FIELD_TEACHER_NAME].toSet();
 1744 #endif
 1745     for(int i=0; i<gt.rules.teachersList.size(); i++){
 1746         Teacher* t=gt.rules.teachersList[i];
 1747         if(tmpSet.contains(t->name))
 1748             dataWarning<<Import::tr("%1 is already in FET data.").arg(t->name);
 1749     }
 1750     //check if already in memory (end)
 1751 
 1752     QDialog* newParent2;
 1753     ok = showFieldsAndWarnings(newParent, newParent2);
 1754     //DON'T ADD THIS! newParent2->deleteLater();
 1755     newParent=newParent2;
 1756     if(!ok) return;
 1757 
 1758     //add teachers (start) - similar to teachersform.cpp by Liviu modified by Volker
 1759     tmpSet.clear();
 1760     for(Teacher* tch : qAsConst(gt.rules.teachersList))
 1761         tmpSet.insert(tch->name);
 1762     int count=0;
 1763     for(int i=0; i<fieldList[FIELD_TEACHER_NAME].size(); i++){
 1764         if(!fieldList[FIELD_TEACHER_NAME][i].isEmpty() && !tmpSet.contains(fieldList[FIELD_TEACHER_NAME][i])){
 1765             tmpSet.insert(fieldList[FIELD_TEACHER_NAME][i]);
 1766             Teacher* tch=new Teacher();
 1767             tch->name=fieldList[FIELD_TEACHER_NAME][i];
 1768             if(!gt.rules.addTeacherFast(tch)){
 1769                 delete tch;
 1770                 assert(0);
 1771             } else count++;
 1772         }
 1773     }
 1774     QMessageBox::information(newParent, tr("FET information"), Import::tr("%1 teachers added. Please check teachers form.").arg(count));
 1775     //add teachers (end) - similar to teachersform.cpp by Liviu modified by Volker
 1776     int tmp=fileName.lastIndexOf(FILE_SEP);
 1777     IMPORT_DIRECTORY=fileName.left(tmp);
 1778     //gt.rules.internalStructureComputed=false;
 1779 }
 1780 
 1781 void Import::importCSVStudents(QWidget* parent){
 1782     prearrangement();
 1783     fieldNumber[FIELD_YEAR_NAME]=IMPORT_DEFAULT_ITEM;
 1784     fieldNumber[FIELD_YEAR_NUMBER_OF_STUDENTS]=IMPORT_DEFAULT_ITEM;
 1785     fieldNumber[FIELD_GROUP_NAME]=IMPORT_DEFAULT_ITEM;
 1786     fieldNumber[FIELD_GROUP_NUMBER_OF_STUDENTS]=IMPORT_DEFAULT_ITEM;
 1787     fieldNumber[FIELD_SUBGROUP_NAME]=IMPORT_DEFAULT_ITEM;
 1788     fieldNumber[FIELD_SUBGROUP_NUMBER_OF_STUDENTS]=IMPORT_DEFAULT_ITEM;
 1789     int ok;
 1790 
 1791     QDialog* newParent;
 1792     ok = getFileSeparatorFieldsAndHead(parent, newParent);
 1793     //DON'T ADD THIS! newParent->deleteLater();
 1794     if(!ok) return;
 1795     
 1796     if(fieldNumber[FIELD_YEAR_NAME]==IMPORT_DEFAULT_ITEM){
 1797         QDialog* newParent2=new ChooseFieldsDialog(newParent);
 1798         const QString settingsName=QString("ImportYearsGroupsSubgroupsChooseFieldsDialog");
 1799         //DON'T ADD THIS! newParent2->deleteLater();
 1800         newParent=newParent2;
 1801         ChooseFieldsDialog& cfd=(*((ChooseFieldsDialog*)newParent));
 1802         int w=chooseWidth(cfd.sizeHint().width());
 1803         int h=chooseHeight(cfd.sizeHint().height());
 1804         cfd.resize(w,h);
 1805 
 1806         centerWidgetOnScreen(&cfd);
 1807         restoreFETDialogGeometry(&cfd, settingsName);
 1808 
 1809         ok=cfd.exec();
 1810         saveFETDialogGeometry(&cfd, settingsName);
 1811         if(!ok) return;
 1812     }
 1813 
 1814     ok = readFields(newParent);
 1815     if(!ok) return;
 1816 
 1817     //check if already in memory (start) - similar to adding items by Liviu modified by Volker
 1818     QString yearName;
 1819     QString groupName;
 1820     QString subgroupName;
 1821     QSet<QString> usedCSVYearNames;         // this is much faster than QStringList
 1822     QSet<QString> usedCSVGroupNames;
 1823     QSet<QString> usedCSVSubgroupNames;
 1824 
 1825     //check csv
 1826     QProgressDialog* _progress=new QProgressDialog(newParent);
 1827     QProgressDialog& progress=(*_progress);
 1828     progress.setWindowTitle(tr("Importing", "Title of a progress dialog"));
 1829     //cout<<"progress in importCSVStudents starts, range="<<fieldList[FIELD_YEAR_NAME].size()<<endl;
 1830     progress.setLabelText(tr("Checking CSV"));
 1831     progress.setModal(true);
 1832     progress.setRange(0, qMax(fieldList[FIELD_YEAR_NAME].size(), 1));
 1833     for(int i=0; i<fieldList[FIELD_YEAR_NAME].size(); i++){
 1834         progress.setValue(i);
 1835         if(progress.wasCanceled()){
 1836             progress.setValue(fieldList[FIELD_YEAR_NAME].size());
 1837             QMessageBox::warning(newParent, "FET", Import::tr("Checking CSV canceled by user."));
 1838             return;
 1839         }
 1840         if(fieldNumber[FIELD_YEAR_NAME]>=0)
 1841             yearName=fieldList[FIELD_YEAR_NAME][i];
 1842         else
 1843             yearName=fieldDefaultItem[FIELD_YEAR_NAME];
 1844         if((fieldNumber[FIELD_GROUP_NAME])>=0)
 1845             groupName=fieldList[FIELD_GROUP_NAME][i];
 1846         else
 1847             groupName=fieldDefaultItem[FIELD_GROUP_NAME];
 1848         if((fieldNumber[FIELD_SUBGROUP_NAME])>=0)
 1849             subgroupName=fieldList[FIELD_SUBGROUP_NAME][i];
 1850         else
 1851             subgroupName=fieldDefaultItem[FIELD_SUBGROUP_NAME];
 1852         if((fieldNumber[FIELD_YEAR_NAME])>=IMPORT_DEFAULT_ITEM){
 1853             if(!yearName.isEmpty())
 1854                 if(!usedCSVYearNames.contains(yearName))
 1855                     usedCSVYearNames<<yearName;
 1856         }
 1857         if((fieldNumber[FIELD_GROUP_NAME])>=IMPORT_DEFAULT_ITEM){
 1858             if(!groupName.isEmpty())
 1859                 if(!usedCSVGroupNames.contains(groupName))
 1860                     usedCSVGroupNames<<groupName;
 1861             if(usedCSVYearNames.contains(groupName))
 1862                 warnText+=Import::tr("Problem in line %1: Group name %2 is taken for a year - please consider another name").arg(fieldList[FIELD_LINE_NUMBER][i]).arg(groupName)+"\n";
 1863             if(usedCSVGroupNames.contains(yearName))
 1864                 warnText+=Import::tr("Problem in line %1: Year name %2 is taken for a group - please consider another name").arg(fieldList[FIELD_LINE_NUMBER][i]).arg(yearName)+"\n";
 1865 
 1866         }
 1867         if((fieldNumber[FIELD_SUBGROUP_NAME])>=IMPORT_DEFAULT_ITEM){
 1868             if(!subgroupName.isEmpty())
 1869                 if(!usedCSVSubgroupNames.contains(subgroupName))
 1870                     usedCSVSubgroupNames<<subgroupName;
 1871             if(usedCSVYearNames.contains(subgroupName))
 1872                 warnText+=Import::tr("Problem in line %1: Subgroup name %2 is taken for a year - please consider another name").arg(fieldList[FIELD_LINE_NUMBER][i]).arg(subgroupName)+"\n";
 1873             if(usedCSVGroupNames.contains(subgroupName))
 1874                 warnText+=Import::tr("Problem in line %1: Subgroup name %2 is taken for a group - please consider another name").arg(fieldList[FIELD_LINE_NUMBER][i]).arg(subgroupName)+"\n";
 1875             if(usedCSVSubgroupNames.contains(groupName))
 1876                 warnText+=Import::tr("Problem in line %1: Group name %2 is taken for a subgroup - please consider another name").arg(fieldList[FIELD_LINE_NUMBER][i]).arg(groupName)+"\n";
 1877             if(usedCSVSubgroupNames.contains(yearName))
 1878                 warnText+=Import::tr("Problem in line %1: Year name %2 is taken for a subgroup - please consider another name").arg(fieldList[FIELD_LINE_NUMBER][i]).arg(yearName)+"\n";
 1879         }
 1880     }
 1881     progress.setValue(qMax(fieldList[FIELD_YEAR_NAME].size(), 1));
 1882     //cout<<"progress in importCSVStudents ends"<<endl;
 1883 
 1884     //check current data
 1885     QProgressDialog* _progress2=new QProgressDialog(newParent);
 1886     QProgressDialog& progress2=(*_progress2);
 1887     progress2.setWindowTitle(tr("Importing", "Title of a progress dialog"));
 1888     progress2.setLabelText(tr("Checking data"));
 1889     progress2.setModal(true);
 1890     progress2.setRange(0, qMax(fieldList[FIELD_YEAR_NAME].size(), 1));
 1891     //cout<<"progress2 in importCSVStudents starts, range="<<fieldList[FIELD_YEAR_NAME].size()<<endl;
 1892     int kk=0;
 1893     for(int i=0; i<gt.rules.yearsList.size(); i++){
 1894         progress2.setValue(kk);
 1895         kk++;
 1896         if(progress2.wasCanceled()){
 1897             progress2.setValue(fieldList[FIELD_YEAR_NAME].size());
 1898             QMessageBox::warning(newParent, "FET", Import::tr("Checking data canceled by user."));
 1899             return;
 1900         }
 1901         StudentsYear* sty=gt.rules.yearsList[i];
 1902         if(usedCSVYearNames.contains(sty->name))
 1903             dataWarning<<Import::tr("Year %1 is already in FET data.").arg(sty->name);
 1904         if(usedCSVGroupNames.contains(sty->name))
 1905             dataWarning<<Import::tr("Can't import group %1. Name is already taken for a year.").arg(sty->name);
 1906         if(usedCSVSubgroupNames.contains(sty->name))
 1907             dataWarning<<Import::tr("Can't import subgroup %1. Name is already taken for a year.").arg(sty->name);
 1908         for(int j=0; j<sty->groupsList.size(); j++){
 1909             progress2.setValue(kk);
 1910             kk++;
 1911             if(progress2.wasCanceled()){
 1912                 progress2.setValue(fieldList[FIELD_YEAR_NAME].size());
 1913                 QMessageBox::warning(newParent, "FET", Import::tr("Checking data canceled by user."));
 1914                 return;
 1915             }
 1916 
 1917             StudentsGroup* stg=sty->groupsList[j];
 1918             if(usedCSVYearNames.contains(stg->name))
 1919                 dataWarning<<Import::tr("Can't import year %1. Name is already taken for a group.").arg(stg->name);
 1920             if(usedCSVGroupNames.contains(stg->name))
 1921                 dataWarning<<Import::tr("Group name %1 is already in FET data (in the same or in another year).").arg(stg->name);
 1922             if(usedCSVSubgroupNames.contains(stg->name))
 1923                 dataWarning<<Import::tr("Can't import subgroup %1. Name is already taken for a group.").arg(stg->name);
 1924             for(int k=0; k<stg->subgroupsList.size(); k++){
 1925                 progress2.setValue(kk);
 1926                 kk++;
 1927 
 1928                 if(progress2.wasCanceled()){
 1929                     progress2.setValue(fieldList[FIELD_YEAR_NAME].size());
 1930                     QMessageBox::warning(newParent, "FET", Import::tr("Checking data canceled by user."));
 1931                     return;
 1932                 }
 1933 
 1934                 StudentsSubgroup* sts=stg->subgroupsList[k];
 1935                 if(usedCSVYearNames.contains(sts->name))
 1936                     dataWarning<<Import::tr("Can't import year %1. Name is already taken for a subgroup.").arg(sts->name);
 1937                 if(usedCSVGroupNames.contains(sts->name))
 1938                     dataWarning<<Import::tr("Can't import group %1. Name is taken for a subgroup.").arg(sts->name);
 1939                 if(usedCSVSubgroupNames.contains(sts->name))
 1940                     dataWarning<<Import::tr("Subgroup name %1 is already in FET data (in the same or in another group).").arg(sts->name);
 1941             }
 1942         }
 1943     }
 1944     progress2.setValue(qMax(fieldList[FIELD_YEAR_NAME].size(), 1));
 1945     //cout<<"progress2 in importCSVStudents ends"<<endl;
 1946 
 1947     QDialog* newParent2;
 1948     ok = showFieldsAndWarnings(newParent, newParent2);
 1949     //DON'T ADD THIS! newParent2->deleteLater();
 1950     newParent=newParent2;
 1951     if(!ok) return;
 1952 
 1953     //add students (start) - similar to adding items by Liviu modified by Volker
 1954     lastWarning.clear();
 1955     int addedYears=0;
 1956     int addedGroups=0;
 1957     int addedSubgroups=0;
 1958     QProgressDialog* _progress3=new QProgressDialog(newParent);
 1959     QProgressDialog& progress3=(*_progress3);
 1960     progress3.setWindowTitle(tr("Importing", "Title of a progress dialog"));
 1961     progress3.setLabelText(tr("Importing data"));
 1962     progress3.setModal(true);
 1963     progress3.setRange(0, qMax(fieldList[FIELD_YEAR_NAME].size(), 1));
 1964     //cout<<"progress3 in importCSVStudents starts, range="<<fieldList[FIELD_YEAR_NAME].size()<<endl;
 1965     
 1966     QHash<QString, StudentsSet*> studentsHash;
 1967     QSet<QPair<QString, QString> > groupsInYearSet; //first year, then group
 1968     QSet<QPair<QString, QString> > subgroupsInGroupSet; //first group, then subgroup
 1969     for(StudentsYear* year : qAsConst(gt.rules.yearsList)){
 1970         studentsHash.insert(year->name, year);
 1971         for(StudentsGroup* group : qAsConst(year->groupsList)){
 1972             studentsHash.insert(group->name, group);
 1973             groupsInYearSet.insert(QPair<QString, QString> (year->name, group->name));
 1974             for(StudentsSubgroup* subgroup : qAsConst(group->subgroupsList)){
 1975                 studentsHash.insert(subgroup->name, subgroup);
 1976                 subgroupsInGroupSet.insert(QPair<QString, QString> (group->name, subgroup->name));
 1977             }
 1978         }
 1979     }
 1980     
 1981     for(int i=0; i<fieldList[FIELD_YEAR_NAME].size(); i++){
 1982         progress3.setValue(i);
 1983         if(progress3.wasCanceled()){
 1984             progress3.setValue(fieldList[FIELD_YEAR_NAME].size());
 1985             QMessageBox::warning(newParent, "FET", Import::tr("Importing data canceled by user."));
 1986             //return false;
 1987             ok=false;
 1988             goto ifUserCanceledProgress3;
 1989         }
 1990         ok=true;
 1991         bool tryNext=false;
 1992         if(fieldNumber[FIELD_YEAR_NAME]!=IMPORT_DEFAULT_ITEM)
 1993             yearName=fieldList[FIELD_YEAR_NAME][i];
 1994         else
 1995             yearName=fieldDefaultItem[FIELD_YEAR_NAME];
 1996         assert(!yearName.isEmpty());
 1997         //StudentsSet* ss=gt.rules.searchStudentsSet(yearName);
 1998         StudentsSet* ss=studentsHash.value(yearName, NULL);
 1999         if(ss!=NULL){
 2000             if(ss->type==STUDENTS_SUBGROUP)
 2001                 ok=false;
 2002             else if(ss->type==STUDENTS_GROUP)
 2003                 ok=false;
 2004             else if(ss->type==STUDENTS_YEAR){
 2005                 ok=false;
 2006                 tryNext=true;
 2007             }
 2008             else
 2009                 assert(0);
 2010         }
 2011         if(ok){
 2012             StudentsYear* sy=new StudentsYear();
 2013             sy->name=yearName;
 2014             QString tmpString=fieldList[FIELD_YEAR_NUMBER_OF_STUDENTS][i];
 2015             sy->numberOfStudents=tmpString.toInt();
 2016             assert(!fieldList[FIELD_YEAR_NUMBER_OF_STUDENTS].isEmpty());
 2017             /*if(gt.rules.searchYear(yearName) >=0 )
 2018                 delete sy;
 2019             else {
 2020                 bool tmp=gt.rules.addYear(sy);
 2021                 assert(tmp);
 2022                 addedYears++;
 2023             }*/
 2024             StudentsSet* studentsSet=ss; //studentsHash.value(yearName, NULL);
 2025             bool yearExists=false;
 2026             if(studentsSet!=NULL){
 2027                 assert(0);
 2028                 if(studentsSet->type==STUDENTS_YEAR)
 2029                     yearExists=true;
 2030             }
 2031             if(yearExists){
 2032                 delete sy;
 2033                 assert(0);
 2034             }
 2035             else{
 2036                 bool tmp=gt.rules.addYearFast(sy);
 2037                 assert(tmp);
 2038                 addedYears++;
 2039                 studentsHash.insert(sy->name, sy);
 2040             }
 2041         }
 2042         if((tryNext || ok) && fieldNumber[FIELD_GROUP_NAME]!=DO_NOT_IMPORT){
 2043             ok=true;
 2044             tryNext=false;
 2045             StudentsGroup* sg;
 2046             sg=NULL;
 2047             if(fieldNumber[FIELD_GROUP_NAME]!=IMPORT_DEFAULT_ITEM)
 2048                 groupName=fieldList[FIELD_GROUP_NAME][i];
 2049             else
 2050                 groupName=fieldDefaultItem[FIELD_GROUP_NAME];
 2051             if(groupName.isEmpty())
 2052                 ok=false;
 2053             else {
 2054                 //if(ok && gt.rules.searchGroup(yearName, groupName)>=0){
 2055                 if(ok && groupsInYearSet.contains(QPair<QString, QString> (yearName, groupName))){
 2056                     ok=false;
 2057                     tryNext=true;
 2058                 }
 2059                 //StudentsSet* ss=gt.rules.searchStudentsSet(groupName);
 2060                 StudentsSet* ss=studentsHash.value(groupName, NULL);
 2061                 if(ss!=NULL && ss->type==STUDENTS_YEAR)
 2062                     ok=false;
 2063                 else if(ss!=NULL && ss->type==STUDENTS_SUBGROUP)
 2064                     ok=false;
 2065                 else if(ss!=NULL && ss->type==STUDENTS_GROUP){
 2066                     if(fieldNumber[FIELD_SUBGROUP_NAME]==DO_NOT_IMPORT)
 2067                         lastWarning+=Import::tr("Group name %1 exists in another year. It means that some years share the same group.").arg(groupName)+"\n";
 2068                     if(fieldNumber[FIELD_SUBGROUP_NAME]!=DO_NOT_IMPORT)
 2069                         if(fieldList[FIELD_SUBGROUP_NAME].isEmpty())
 2070                             lastWarning+=Import::tr("Group name %1 exists in another year. It means that some years share the same group.").arg(groupName)+"\n";
 2071                 }
 2072                 if(ss!=NULL&&ok){
 2073                     sg=(StudentsGroup*)ss;
 2074                 }
 2075                 else if(ss==NULL&&ok){
 2076                     sg=new StudentsGroup();
 2077                     sg->name=groupName;
 2078                     QString tmpString=fieldList[FIELD_GROUP_NUMBER_OF_STUDENTS][i];
 2079                     sg->numberOfStudents=tmpString.toInt();
 2080                     assert(ok);
 2081                     assert(!fieldList[FIELD_GROUP_NUMBER_OF_STUDENTS].isEmpty());
 2082 
 2083                     studentsHash.insert(sg->name, sg);
 2084                 }
 2085                 if(ok){
 2086                     StudentsSet* tmpStudentsSet=studentsHash.value(yearName, NULL);
 2087                     assert(tmpStudentsSet->type==STUDENTS_YEAR);
 2088                     
 2089                     StudentsYear* year=(StudentsYear*)tmpStudentsSet;
 2090                     assert(year!=NULL);
 2091                     gt.rules.addGroupFast(year, sg);
 2092 
 2093                     groupsInYearSet.insert(QPair<QString, QString> (yearName, sg->name));
 2094 
 2095                     addedGroups++;
 2096                 }
 2097             }
 2098         }
 2099         if((tryNext || ok) && fieldNumber[FIELD_SUBGROUP_NAME]!=DO_NOT_IMPORT){
 2100             ok=true;
 2101             if(fieldNumber[FIELD_SUBGROUP_NAME]!=IMPORT_DEFAULT_ITEM)
 2102                 subgroupName=fieldList[FIELD_SUBGROUP_NAME][i];
 2103             else
 2104                 subgroupName=fieldDefaultItem[FIELD_SUBGROUP_NAME];
 2105             if(subgroupName.isEmpty())
 2106                 ok=false;
 2107             else {
 2108                 //if(ok && gt.rules.searchSubgroup(yearName, groupName, subgroupName)>=0){
 2109                 if(ok && subgroupsInGroupSet.contains(QPair<QString, QString> (groupName, subgroupName))){
 2110                     ok=false;
 2111                 }
 2112                 //StudentsSet* ss=gt.rules.searchStudentsSet(subgroupName);
 2113                 StudentsSet* ss=studentsHash.value(subgroupName, NULL);
 2114                 StudentsSubgroup* sts;
 2115                 sts=NULL;
 2116                 if(ss!=NULL && ss->type==STUDENTS_YEAR){
 2117                     ok=false;
 2118                 }
 2119                 else if(ss!=NULL && ss->type==STUDENTS_GROUP){
 2120                     ok=false;
 2121                 }
 2122                 else if(ss!=NULL && ss->type==STUDENTS_SUBGROUP){
 2123                     lastWarning+=Import::tr("Subgroup name %1 exists in another group. It means that some groups share the same subgroup.").arg(subgroupName)+"\n";
 2124                 }
 2125                 if(ss!=NULL&&ok){
 2126                     sts=(StudentsSubgroup*)ss;
 2127                 }
 2128                 else if(ss==NULL&&ok) {
 2129                     sts=new StudentsSubgroup();
 2130                     sts->name=subgroupName;
 2131                     QString tmpString=fieldList[FIELD_SUBGROUP_NUMBER_OF_STUDENTS][i];
 2132                     sts->numberOfStudents=tmpString.toInt();
 2133                     assert(ok);
 2134                     assert(!fieldList[FIELD_SUBGROUP_NUMBER_OF_STUDENTS].isEmpty());
 2135 
 2136                     studentsHash.insert(sts->name, sts);
 2137                 }
 2138                 if(ok){
 2139                     StudentsSet* tmpStudentsSet=studentsHash.value(yearName, NULL);
 2140                     assert(tmpStudentsSet->type==STUDENTS_YEAR);
 2141                 
 2142                     StudentsYear* year=(StudentsYear*)tmpStudentsSet;
 2143                     assert(year!=NULL);
 2144                     
 2145                     tmpStudentsSet=studentsHash.value(groupName, NULL);
 2146                     assert(tmpStudentsSet->type==STUDENTS_GROUP);
 2147                     
 2148                     StudentsGroup* group=(StudentsGroup*)tmpStudentsSet;
 2149                     assert(group!=NULL);
 2150 
 2151                     gt.rules.addSubgroupFast(year, group, sts);
 2152 
 2153                     subgroupsInGroupSet.insert(QPair<QString, QString> (groupName, sts->name));
 2154 
 2155                     addedSubgroups++;
 2156                 }
 2157             }
 2158         }
 2159     }
 2160 
 2161     progress3.setValue(qMax(fieldList[FIELD_YEAR_NAME].size(), 1));
 2162     //cout<<"progress3 in importCSVStudents ends"<<endl;
 2163     //add students (end) - similar to adding items by Liviu modified by Volker
 2164     
 2165 ifUserCanceledProgress3:
 2166 
 2167     if(!lastWarning.isEmpty())
 2168         lastWarning.insert(0,"\n"+Import::tr("Notes:")+"\n");
 2169     lastWarning.insert(0,Import::tr("%1 subgroups added. Please check subgroups form.").arg(addedSubgroups)+"\n");
 2170     lastWarning.insert(0,Import::tr("%1 groups added. Please check groups form.").arg(addedGroups)+"\n");
 2171     lastWarning.insert(0,Import::tr("%1 years added. Please check years form.").arg(addedYears)+"\n");
 2172     
 2173     gt.rules.computePermanentStudentsHash();
 2174 
 2175     LastWarningsDialog lwd(newParent);
 2176     int w=chooseWidth(lwd.sizeHint().width());
 2177     int h=chooseHeight(lwd.sizeHint().height());
 2178     lwd.resize(w,h);
 2179     centerWidgetOnScreen(&lwd);
 2180 
 2181     ok=lwd.exec();
 2182 
 2183     int tmp=fileName.lastIndexOf(FILE_SEP);
 2184     IMPORT_DIRECTORY=fileName.left(tmp);
 2185     //gt.rules.internalStructureComputed=false;
 2186 }
 2187 
 2188 void Import::importCSVActivities(QWidget* parent){
 2189     prearrangement();
 2190     fieldNumber[FIELD_STUDENTS_SET]=IMPORT_DEFAULT_ITEM;
 2191     fieldNumber[FIELD_SUBJECT_NAME]=IMPORT_DEFAULT_ITEM;
 2192     fieldNumber[FIELD_TEACHERS_SET]=IMPORT_DEFAULT_ITEM;
 2193     fieldNumber[FIELD_ACTIVITY_TAGS_SET]=IMPORT_DEFAULT_ITEM;
 2194     fieldNumber[FIELD_TOTAL_DURATION]=IMPORT_DEFAULT_ITEM;
 2195     fieldNumber[FIELD_SPLIT_DURATION]=IMPORT_DEFAULT_ITEM;
 2196     fieldNumber[FIELD_MIN_DAYS]=IMPORT_DEFAULT_ITEM;
 2197     fieldNumber[FIELD_MIN_DAYS_WEIGHT]=IMPORT_DEFAULT_ITEM;
 2198     fieldNumber[FIELD_MIN_DAYS_CONSECUTIVE]=IMPORT_DEFAULT_ITEM;
 2199 
 2200     int ok;
 2201 
 2202     QDialog* newParent;
 2203     ok = getFileSeparatorFieldsAndHead(parent, newParent);
 2204     //DON'T ADD THIS! newParent->deleteLater();
 2205     if(!ok) return;
 2206 
 2207     if(fieldNumber[FIELD_SUBJECT_NAME]==IMPORT_DEFAULT_ITEM){
 2208         QDialog* newParent2=new ChooseFieldsDialog(newParent);
 2209         const QString settingsName=QString("ImportActivitiesChooseFieldsDialog");
 2210         //DON'T ADD THIS! newParent2->deleteLater();
 2211         newParent=newParent2;
 2212         ChooseFieldsDialog& cfd=(*((ChooseFieldsDialog*)newParent));
 2213         int w=chooseWidth(cfd.sizeHint().width());
 2214         int h=chooseHeight(cfd.sizeHint().height());
 2215         cfd.resize(w,h);
 2216         centerWidgetOnScreen(&cfd);
 2217         restoreFETDialogGeometry(&cfd, settingsName);
 2218 
 2219         ok=cfd.exec();
 2220         saveFETDialogGeometry(&cfd, settingsName);
 2221     }
 2222     if(!ok) return;
 2223 
 2224     if(fieldNumber[FIELD_SPLIT_DURATION]==DO_NOT_IMPORT&&fieldNumber[FIELD_TOTAL_DURATION]==DO_NOT_IMPORT){
 2225         QMessageBox::warning(newParent, tr("FET warning"), Import::tr("FET needs to know %1 or %2 if you import %3.").arg(fieldName[FIELD_SPLIT_DURATION]).arg(fieldName[FIELD_TOTAL_DURATION]).arg(importThing));
 2226         return;
 2227     }
 2228 
 2229     ok = readFields(newParent);
 2230     if(!ok) return;
 2231 
 2232     //check number of fields (start) //because of bug reported 17.03.2008
 2233     int checkNumber=0;
 2234     if(fieldList[FIELD_STUDENTS_SET].size()>0){
 2235         checkNumber=fieldList[FIELD_STUDENTS_SET].size();
 2236     }
 2237     if(fieldList[FIELD_SUBJECT_NAME].size()>0){
 2238         if(checkNumber>0){
 2239             assert(checkNumber==fieldList[FIELD_SUBJECT_NAME].size());
 2240         }
 2241         checkNumber=fieldList[FIELD_SUBJECT_NAME].size();
 2242     }
 2243     if(fieldList[FIELD_TEACHERS_SET].size()>0){
 2244         if(checkNumber>0){
 2245             assert(checkNumber==fieldList[FIELD_TEACHERS_SET].size());
 2246         }
 2247         checkNumber=fieldList[FIELD_TEACHERS_SET].size();
 2248     }
 2249     if(fieldList[FIELD_ACTIVITY_TAGS_SET].size()>0){
 2250         if(checkNumber>0){
 2251             assert(checkNumber==fieldList[FIELD_ACTIVITY_TAGS_SET].size());
 2252         }
 2253         checkNumber=fieldList[FIELD_ACTIVITY_TAGS_SET].size();
 2254     }
 2255     if(fieldList[FIELD_TOTAL_DURATION].size()>0){
 2256         if(checkNumber>0){
 2257             assert(checkNumber==fieldList[FIELD_TOTAL_DURATION].size());
 2258         }
 2259         checkNumber=fieldList[FIELD_TOTAL_DURATION].size();
 2260     }
 2261     if(fieldList[FIELD_SPLIT_DURATION].size()>0){
 2262         if(checkNumber>0){
 2263             assert(checkNumber==fieldList[FIELD_SPLIT_DURATION].size());
 2264         }
 2265         checkNumber=fieldList[FIELD_SPLIT_DURATION].size();
 2266     }
 2267     if(fieldList[FIELD_MIN_DAYS].size()>0){
 2268         if(checkNumber>0){
 2269             assert(checkNumber==fieldList[FIELD_MIN_DAYS].size());
 2270         }
 2271         checkNumber=fieldList[FIELD_MIN_DAYS].size();
 2272     }
 2273     if(fieldList[FIELD_MIN_DAYS_WEIGHT].size()>0){
 2274         if(checkNumber>0){
 2275             assert(checkNumber==fieldList[FIELD_MIN_DAYS_WEIGHT].size());
 2276         }
 2277         checkNumber=fieldList[FIELD_MIN_DAYS_WEIGHT].size();
 2278     }
 2279     if(fieldList[FIELD_MIN_DAYS_CONSECUTIVE].size()>0){
 2280         if(checkNumber>0){
 2281             assert(checkNumber==fieldList[FIELD_MIN_DAYS_CONSECUTIVE].size());
 2282         }
 2283         checkNumber=fieldList[FIELD_MIN_DAYS_CONSECUTIVE].size();
 2284     }
 2285 
 2286     if(fieldList[FIELD_STUDENTS_SET].size()==0){
 2287         for(int i=0; i<checkNumber; i++)
 2288             fieldList[FIELD_STUDENTS_SET]<<"";
 2289     }
 2290     if(fieldList[FIELD_SUBJECT_NAME].size()==0){
 2291         for(int i=0; i<checkNumber; i++)
 2292             fieldList[FIELD_SUBJECT_NAME]<<"";
 2293     }
 2294     if(fieldList[FIELD_TEACHERS_SET].size()==0){
 2295         for(int i=0; i<checkNumber; i++)
 2296             fieldList[FIELD_TEACHERS_SET]<<"";
 2297     }
 2298     if(fieldList[FIELD_ACTIVITY_TAGS_SET].size()==0){
 2299         for(int i=0; i<checkNumber; i++)
 2300             fieldList[FIELD_ACTIVITY_TAGS_SET]<<"";
 2301     }
 2302     if(fieldList[FIELD_TOTAL_DURATION].size()==0){
 2303         for(int i=0; i<checkNumber; i++)
 2304             fieldList[FIELD_TOTAL_DURATION]<<"1";
 2305     }
 2306     if(fieldList[FIELD_SPLIT_DURATION].size()==0){
 2307         for(int i=0; i<checkNumber; i++)
 2308             fieldList[FIELD_SPLIT_DURATION]<<"1";
 2309     }
 2310     if(fieldList[FIELD_MIN_DAYS].size()==0){
 2311         for(int i=0; i<checkNumber; i++)
 2312             fieldList[FIELD_MIN_DAYS]<<"1";
 2313     }
 2314     if(fieldList[FIELD_MIN_DAYS_WEIGHT].size()==0){
 2315         for(int i=0; i<checkNumber; i++)
 2316             fieldList[FIELD_MIN_DAYS_WEIGHT]<<"95";
 2317     }
 2318     if(fieldList[FIELD_MIN_DAYS_CONSECUTIVE].size()==0){
 2319         for(int i=0; i<checkNumber; i++)
 2320             fieldList[FIELD_MIN_DAYS_CONSECUTIVE]<<"no";
 2321     }
 2322 
 2323     //check number of fields (end) //because of bug reported 17.03.2008
 2324 
 2325     //check if already in memory (start)
 2326     //check if students set is in memory
 2327     /*QHash<QString, StudentsSet*> studentsHash;
 2328     for(StudentsYear* year : qAsConst(gt.rules.yearsList)){
 2329         studentsHash.insert(year->name, year);
 2330         for(StudentsGroup* group : qAsConst(year->groupsList)){
 2331             studentsHash.insert(group->name, group);
 2332             for(StudentsSubgroup* subgroup : qAsConst(group->subgroupsList)){
 2333                 studentsHash.insert(subgroup->name, subgroup);
 2334             }
 2335         }
 2336     }*/
 2337     const QHash<QString, StudentsSet*>& studentsHash=gt.rules.permanentStudentsHash;
 2338     
 2339     lastWarning.clear();
 2340     QString line;
 2341     QStringList students;
 2342     bool firstWarning=true;
 2343     for(int i=0; i<fieldList[FIELD_STUDENTS_SET].size(); i++){
 2344         line.clear();
 2345         line=fieldList[FIELD_STUDENTS_SET][i];
 2346         students.clear();
 2347 #if QT_VERSION >= QT_VERSION_CHECK(5,15,0)
 2348         students=line.split("+", Qt::SkipEmptyParts);
 2349 #else
 2350         students=line.split("+", QString::SkipEmptyParts);
 2351 #endif
 2352         if(!fieldList[FIELD_STUDENTS_SET][i].isEmpty()){
 2353             for(int s=0; s<students.size(); s++){
 2354                 //StudentsSet* ss=gt.rules.searchStudentsSet(students[s]);
 2355                 StudentsSet* ss=studentsHash.value(students[s], NULL);
 2356                 if(ss==NULL){
 2357                     if(firstWarning){
 2358                         lastWarning+=Import::tr("FET can't import activities, because FET needs to know the structure of the "
 2359                         "students sets. You must add (or import) years, groups and subgroups first.")+"\n"+
 2360                         tr("It is recommended to import also teachers, rooms, buildings, subjects and activity tags before "
 2361                         "importing activities. It is not needed, because FET will automatically do it, but you can "
 2362                         "check the activity csv file by that.")+"\n";
 2363                         firstWarning=false;
 2364                     }
 2365                     lastWarning+=Import::tr("Students set %1 doesn't exist. You must add (or import) years, groups and subgroups first.").arg(students[s])+"\n";
 2366                 }
 2367             }
 2368         }
 2369     }
 2370     if(lastWarning.size()>0){
 2371         QDialog* newParent2=new LastWarningsDialog(newParent);
 2372         //DON'T ADD THIS! newParent2->deleteLater();
 2373         newParent=newParent2;
 2374         LastWarningsDialog& lwd=(*((LastWarningsDialog*)newParent));
 2375         int w=chooseWidth(lwd.sizeHint().width());
 2376         int h=chooseHeight(lwd.sizeHint().height());
 2377         lwd.resize(w,h);
 2378         centerWidgetOnScreen(&lwd);
 2379 
 2380         ok=lwd.exec();
 2381         return;
 2382     }
 2383     //check if teacher is in memory
 2384     assert(fieldList[FIELD_TEACHER_NAME].isEmpty());
 2385     QStringList teachers;
 2386     QSet<QString> tmpSet;
 2387     tmpSet.clear();
 2388     for(int i=0; i<gt.rules.teachersList.size(); i++){
 2389         Teacher* t=gt.rules.teachersList[i];
 2390         tmpSet.insert(t->name);
 2391     }
 2392     for(int i=0; i<fieldList[FIELD_TEACHERS_SET].size(); i++){
 2393         line.clear();
 2394         line=fieldList[FIELD_TEACHERS_SET][i];
 2395         teachers.clear();
 2396 #if QT_VERSION >= QT_VERSION_CHECK(5,15,0)
 2397         teachers=line.split("+", Qt::SkipEmptyParts);
 2398 #else
 2399         teachers=line.split("+", QString::SkipEmptyParts);
 2400 #endif
 2401         for(int t=0; t<teachers.size(); t++){
 2402             bool add=true;
 2403             if(tmpSet.contains(teachers[t]) || teachers[t]=="")
 2404                 add=false;
 2405             if(add){
 2406                 dataWarning<<Import::tr("%1 %2 will be added.", "For instance 'Subject Math will be added', so use singular").arg(fieldName[FIELD_TEACHER_NAME]).arg(teachers[t]);
 2407                 tmpSet.insert(teachers[t]);
 2408                 fieldList[FIELD_TEACHER_NAME]<<teachers[t];
 2409             }
 2410         }
 2411     }
 2412     //check if subject is in memory
 2413     tmpSet.clear();
 2414     for(int i=0; i<gt.rules.subjectsList.size(); i++){
 2415         Subject* s=gt.rules.subjectsList[i];
 2416         tmpSet.insert(s->name);
 2417     }
 2418     for(int sn=0; sn<fieldList[FIELD_SUBJECT_NAME].size(); sn++){
 2419         bool add=true;
 2420         if(tmpSet.contains(fieldList[FIELD_SUBJECT_NAME][sn]) || fieldList[FIELD_SUBJECT_NAME][sn]=="")
 2421             add=false;
 2422         if(add){
 2423             dataWarning<<Import::tr("%1 %2 will be added.", "For instance 'Subject Math will be added', so use singular").arg(fieldName[FIELD_SUBJECT_NAME]).arg(fieldList[FIELD_SUBJECT_NAME][sn]);
 2424             tmpSet.insert(fieldList[FIELD_SUBJECT_NAME][sn]);
 2425         }
 2426     }
 2427     //check if activity tag is in memory
 2428     assert(fieldList[FIELD_ACTIVITY_TAG_NAME].isEmpty());
 2429     QStringList activityTags;
 2430     tmpSet.clear();
 2431     for(int i=0; i<gt.rules.activityTagsList.size(); i++){
 2432         ActivityTag* at=gt.rules.activityTagsList[i];
 2433         tmpSet.insert(at->name);
 2434     }
 2435     for(int i=0; i<fieldList[FIELD_ACTIVITY_TAGS_SET].size(); i++){
 2436         line.clear();
 2437         line=fieldList[FIELD_ACTIVITY_TAGS_SET][i];
 2438         activityTags.clear();
 2439 #if QT_VERSION >= QT_VERSION_CHECK(5,15,0)
 2440         activityTags=line.split("+", Qt::SkipEmptyParts);
 2441 #else
 2442         activityTags=line.split("+", QString::SkipEmptyParts);
 2443 #endif
 2444         for(int at=0; at<activityTags.size(); at++){
 2445             bool add=true;
 2446             if(tmpSet.contains(activityTags[at]) || activityTags[at]=="")
 2447                 add=false;
 2448             if(add){
 2449                 dataWarning<<Import::tr("%1 %2 will be added.", "For instance 'Subject Math will be added', so use singular").arg(fieldName[FIELD_ACTIVITY_TAG_NAME]).arg(activityTags[at]);
 2450                 tmpSet.insert(activityTags[at]);
 2451                 fieldList[FIELD_ACTIVITY_TAG_NAME]<<activityTags[at];
 2452             }
 2453         }
 2454     }
 2455     tmpSet.clear();
 2456     //check if already in memory (end)
 2457 
 2458     QDialog* newParent2;
 2459     ok = showFieldsAndWarnings(newParent, newParent2);
 2460     //DON'T ADD THIS! newParent2->deleteLater();
 2461     newParent=newParent2;
 2462     if(!ok) return;
 2463 
 2464     //add teachers
 2465     //maybe TODO write a function, so also import teacher csv can share this code
 2466     tmpSet.clear();
 2467     for(Teacher* tch : qAsConst(gt.rules.teachersList))
 2468         tmpSet.insert(tch->name);
 2469     int count=0;
 2470     for(int i=0; i<fieldList[FIELD_TEACHER_NAME].size(); i++){
 2471         if(!fieldList[FIELD_TEACHER_NAME][i].isEmpty()){
 2472             Teacher* tch=new Teacher();
 2473             tch->name=fieldList[FIELD_TEACHER_NAME][i];
 2474             assert(!tmpSet.contains(tch->name));
 2475             if(!gt.rules.addTeacherFast(tch)){
 2476                 delete tch;
 2477                 assert(0);
 2478             } else
 2479                 count++;
 2480             tmpSet.insert(tch->name);
 2481         }
 2482     }
 2483     fieldList[FIELD_TEACHER_NAME].clear();
 2484     if(count>0)
 2485         lastWarning+=Import::tr("%1 teachers added. Please check teachers form.").arg(count)+"\n";
 2486     //add subjects
 2487     //maybe TODO write a function, so also import subjects csv can share this code
 2488     tmpSet.clear();
 2489     for(Subject* sbj : qAsConst(gt.rules.subjectsList))
 2490         tmpSet.insert(sbj->name);
 2491     count=0;
 2492     for(int i=0; i<fieldList[FIELD_SUBJECT_NAME].size(); i++){
 2493         if(!fieldList[FIELD_SUBJECT_NAME][i].isEmpty() && !tmpSet.contains(fieldList[FIELD_SUBJECT_NAME][i])){
 2494             Subject* s=new Subject();
 2495             s->name=fieldList[FIELD_SUBJECT_NAME][i];
 2496             assert(!tmpSet.contains(s->name));
 2497             if(!gt.rules.addSubjectFast(s)){
 2498                 delete s;
 2499                 assert(0);
 2500             } else
 2501                 count++;
 2502             tmpSet.insert(s->name);
 2503         }
 2504     }
 2505     if(count>0)
 2506         lastWarning+=Import::tr("%1 subjects added. Please check subjects form.").arg(count)+"\n";
 2507     //add activity tags
 2508     //maybe TODO write a function, so also import activity tags csv can share this code
 2509     tmpSet.clear();
 2510     for(ActivityTag* at : qAsConst(gt.rules.activityTagsList))
 2511         tmpSet.insert(at->name);
 2512     count=0;
 2513     for(int i=0; i<fieldList[FIELD_ACTIVITY_TAG_NAME].size(); i++){
 2514         if(!fieldList[FIELD_ACTIVITY_TAG_NAME][i].isEmpty()){
 2515             ActivityTag* a=new ActivityTag();
 2516             a->name=fieldList[FIELD_ACTIVITY_TAG_NAME][i];
 2517             assert(!tmpSet.contains(a->name));
 2518             if(!gt.rules.addActivityTag(a)){
 2519                 delete a;
 2520                 assert(0);
 2521             } else
 2522                 count++;
 2523             tmpSet.insert(a->name);
 2524         }
 2525     }
 2526     if(count>0)
 2527         lastWarning+=Import::tr("%1 activity tags added. Please check activity tags form.").arg(count)+"\n";
 2528 
 2529     //add activities (start) - similar to Liviu's code modified by Volker
 2530     count=0;
 2531     int count2=0;
 2532     int activityid=0; //We set the id of this newly added activity = (the largest existing id + 1)
 2533     for(int i=0; i<gt.rules.activitiesList.size(); i++){    //TODO: do it the same in addactivityform.cpp (calculate activity id just one time)
 2534         Activity* act=gt.rules.activitiesList[i];
 2535         if(act->id > activityid)
 2536             activityid = act->id;
 2537     }
 2538     activityid++;
 2539     QProgressDialog* _progress4=new QProgressDialog(newParent);
 2540     QProgressDialog& progress4=(*_progress4);
 2541     progress4.setWindowTitle(tr("Importing", "Title of a progress dialog"));
 2542     progress4.setLabelText(tr("Importing activities"));
 2543     progress4.setModal(true);
 2544     progress4.setRange(0, qMax(fieldList[FIELD_SUBJECT_NAME].size(), 1));
 2545 
 2546     bool incorrect_bool_consecutive=false;
 2547     
 2548     for(int i=0; i<fieldList[FIELD_SUBJECT_NAME].size(); i++){
 2549         progress4.setValue(i);
 2550         if(progress4.wasCanceled()){
 2551             progress4.setValue(fieldList[FIELD_SUBJECT_NAME].size());
 2552             QMessageBox::warning(newParent, "FET", Import::tr("Importing data canceled by user."));
 2553             //return false;
 2554             ok=false;
 2555             goto ifUserCanceledProgress4;
 2556         }
 2557 
 2558         bool ok2;
 2559         QString tmpStr=fieldList[FIELD_MIN_DAYS_WEIGHT][i];
 2560 //      double weight=tmpStr.toDouble(&ok2);
 2561         double weight=customFETStrToDouble(tmpStr, &ok2);
 2562         assert(ok2);
 2563 
 2564         QStringList teachers_namesFromFile;
 2565         if(!fieldList[FIELD_TEACHERS_SET][i].isEmpty())
 2566 #if QT_VERSION >= QT_VERSION_CHECK(5,15,0)
 2567             teachers_namesFromFile = fieldList[FIELD_TEACHERS_SET][i].split("+", Qt::SkipEmptyParts);
 2568 #else
 2569             teachers_namesFromFile = fieldList[FIELD_TEACHERS_SET][i].split("+", QString::SkipEmptyParts);
 2570 #endif
 2571         
 2572         QStringList teachers_names;
 2573         QSet<QString> _teachersSet;
 2574         for(const QString& teacherName : qAsConst(teachers_namesFromFile)){
 2575             //assert(teachersHash.contains(teacherName));
 2576             if(!_teachersSet.contains(teacherName)){
 2577                 _teachersSet.insert(teacherName);
 2578                 teachers_names<<teacherName;
 2579             } else {
 2580                 lastWarning+=tr("Line %1: Activity contains duplicate teacher %2 - please correct that").arg(fieldList[FIELD_LINE_NUMBER][i]).arg(teacherName)+"\n";
 2581             }
 2582         }
 2583         
 2584         QString subject_name = fieldList[FIELD_SUBJECT_NAME][i];
 2585         
 2586         QStringList activity_tags_namesFromFile;
 2587         if(!fieldList[FIELD_ACTIVITY_TAGS_SET][i].isEmpty())
 2588 #if QT_VERSION >= QT_VERSION_CHECK(5,15,0)
 2589             activity_tags_namesFromFile = fieldList[FIELD_ACTIVITY_TAGS_SET][i].split("+", Qt::SkipEmptyParts);
 2590 #else
 2591             activity_tags_namesFromFile = fieldList[FIELD_ACTIVITY_TAGS_SET][i].split("+", QString::SkipEmptyParts);
 2592 #endif
 2593         
 2594         QStringList activity_tags_names;
 2595         QSet<QString> _activityTagsSet;
 2596         for(const QString& activityTag : qAsConst(activity_tags_namesFromFile)){
 2597             //assert(activityTagsHash.contains(activityTag));
 2598             if(!_activityTagsSet.contains(activityTag)){
 2599                 _activityTagsSet.insert(activityTag);
 2600                 activity_tags_names<<activityTag;
 2601             } else {
 2602                 lastWarning+=tr("Line %1: Activity contains duplicate activity tag %2 - please correct that").arg(fieldList[FIELD_LINE_NUMBER][i]).arg(activityTag)+"\n";
 2603             }
 2604         }
 2605         
 2606         QStringList students_namesFromFile;
 2607         if(!fieldList[FIELD_STUDENTS_SET][i].isEmpty())
 2608 #if QT_VERSION >= QT_VERSION_CHECK(5,15,0)
 2609             students_namesFromFile = fieldList[FIELD_STUDENTS_SET][i].split("+", Qt::SkipEmptyParts);
 2610 #else
 2611             students_namesFromFile = fieldList[FIELD_STUDENTS_SET][i].split("+", QString::SkipEmptyParts);
 2612 #endif
 2613 
 2614         int numberOfStudents=0;
 2615         QStringList students_names;
 2616         QSet<QString> _studentsSet;
 2617         for(const QString& studentsSet : qAsConst(students_namesFromFile)){
 2618             assert(studentsHash.contains(studentsSet));
 2619             if(!_studentsSet.contains(studentsSet)){
 2620                 _studentsSet.insert(studentsSet);
 2621                 students_names<<studentsSet;
 2622             } else {
 2623                 lastWarning+=tr("Line %1: Activity contains duplicate students set %2 - please correct that").arg(fieldList[FIELD_LINE_NUMBER][i]).arg(studentsSet)+"\n";
 2624             }
 2625             numberOfStudents+=studentsHash.value(studentsSet)->numberOfStudents;
 2626         }
 2627 
 2628         QStringList splitDurationList;
 2629         splitDurationList.clear();
 2630         assert(!fieldList[FIELD_SPLIT_DURATION][i].isEmpty());
 2631 #if QT_VERSION >= QT_VERSION_CHECK(5,15,0)
 2632         splitDurationList = fieldList[FIELD_SPLIT_DURATION][i].split("+", Qt::SkipEmptyParts);
 2633 #else
 2634         splitDurationList = fieldList[FIELD_SPLIT_DURATION][i].split("+", QString::SkipEmptyParts);
 2635 #endif
 2636         int nsplit=splitDurationList.size();
 2637         if(nsplit==1){
 2638             int duration=fieldList[FIELD_TOTAL_DURATION][i].toInt(&ok2, 10);
 2639             assert(ok2);
 2640             bool active=true;
 2641             //workaround only. Please rethink. (start)
 2642             /*QStringList activity_tag_names;
 2643             activity_tag_names<<activity_tag_name;*/
 2644             //workaround only. Please rethink. (end)
 2645             
 2646             /*Activity a(gt.rules, activityid, 0, teachers_names, subject_name, activity_tags_names, students_names, duration, duration, active, true, -1);
 2647     
 2648             bool already_existing=false;
 2649             for(int i=0; i<gt.rules.activitiesList.size(); i++){
 2650                 Activity* act=gt.rules.activitiesList[i];
 2651                 if((*act)==a)
 2652                     already_existing=true;
 2653             }
 2654             if(already_existing){
 2655                 lastWarning+=Import::tr("Activity %1 already exists. A duplicate activity is imported. Please check the dataset!").arg(activityid)+"\n";
 2656             }*/
 2657             if(duration>0){
 2658                 bool tmp=gt.rules.addSimpleActivityFast(newParent, activityid, 0, teachers_names, subject_name, activity_tags_names,
 2659                     students_names, duration, duration, active, true, -1, numberOfStudents);
 2660                 activityid++;
 2661                 if(tmp){
 2662                     count++;
 2663                     count2++;
 2664                 }
 2665                 else
 2666                     QMessageBox::critical(newParent, tr("FET information"), tr("Activity NOT added - please report error"));
 2667             } else {
 2668                 lastWarning+=tr("Line %1: Activity duration is lower than 1 - please correct that").arg(fieldList[FIELD_LINE_NUMBER][i])+"\n";
 2669             }
 2670         }
 2671         else{ //split activity
 2672             int totalduration;
 2673             int durations[MAX_SPLIT_OF_AN_ACTIVITY];
 2674             bool active[MAX_SPLIT_OF_AN_ACTIVITY];
 2675     
 2676             totalduration=0;
 2677             bool durationOK=true;
 2678             for(int s=0; s<nsplit; s++){
 2679                 durations[s]=splitDurationList[s].toInt(&ok2);
 2680                 assert(ok2);
 2681                 if(durations[s]<1){
 2682                     durationOK=false;
 2683                 }
 2684                 active[s]=true;
 2685                 totalduration+=durations[s];
 2686             }
 2687             if(durationOK){
 2688                 assert(totalduration==fieldList[FIELD_TOTAL_DURATION][i].toInt(&ok2));
 2689                 assert(ok2);
 2690         
 2691                 int minD=fieldList[FIELD_MIN_DAYS][i].toInt(&ok2);
 2692                 assert(ok2);
 2693                 bool force;
 2694                 
 2695                 if(fieldList[FIELD_MIN_DAYS_CONSECUTIVE][i].toUpper()=="YES" ||
 2696                     fieldList[FIELD_MIN_DAYS_CONSECUTIVE][i].toUpper()=="Y" ||
 2697                     fieldList[FIELD_MIN_DAYS_CONSECUTIVE][i].toUpper()=="TRUE" ||
 2698                     fieldList[FIELD_MIN_DAYS_CONSECUTIVE][i].toUpper()=="T" ||
 2699                     fieldList[FIELD_MIN_DAYS_CONSECUTIVE][i].toUpper()=="1"
 2700                 )
 2701                     force=true;
 2702                 else if(
 2703                     fieldList[FIELD_MIN_DAYS_CONSECUTIVE][i].toUpper()=="NO" ||
 2704                     fieldList[FIELD_MIN_DAYS_CONSECUTIVE][i].toUpper()=="N" ||
 2705                     fieldList[FIELD_MIN_DAYS_CONSECUTIVE][i].toUpper()=="FALSE" ||
 2706                     fieldList[FIELD_MIN_DAYS_CONSECUTIVE][i].toUpper()=="F" ||
 2707                     fieldList[FIELD_MIN_DAYS_CONSECUTIVE][i].toUpper()=="0"
 2708                 )
 2709                     force=false;
 2710                 else{
 2711                     incorrect_bool_consecutive=true;
 2712                     force=true;
 2713                 }
 2714                 //workaround only. Please rethink. (start)
 2715                 /*QStringList activity_tag_names;
 2716                 activity_tag_names<<activity_tag_name;*/
 2717                 //workaround only. Please rethink. (end)
 2718                 bool tmp=gt.rules.addSplitActivityFast(newParent, activityid, activityid,
 2719                     teachers_names, subject_name, activity_tags_names, students_names,
 2720                     nsplit, totalduration, durations,
 2721                     active, minD, weight, force, true, -1, numberOfStudents);
 2722                 activityid+=nsplit;
 2723                 if(tmp){
 2724                     count++;
 2725                     count2+=nsplit;
 2726                 }
 2727                 else
 2728                     QMessageBox::critical(newParent, tr("FET information"), tr("Split activity NOT added - error???"));
 2729             } else {
 2730                 lastWarning+=tr("Line %1: Activity duration is lower than 1 - please correct that").arg(fieldList[FIELD_LINE_NUMBER][i])+"\n";
 2731             }
 2732         }
 2733     }
 2734     progress4.setValue(qMax(fieldList[FIELD_SUBJECT_NAME].size(), 1));
 2735     //add activities (end) - similar to Liviu's code modified by Volker
 2736 ifUserCanceledProgress4:
 2737 
 2738     if(incorrect_bool_consecutive){
 2739         lastWarning.insert(0, tr("Warning: found tags for the 'consecutive' field of min days which are not a valid boolean value (%1) - making them %2").arg("1, 0, yes, no, y, n, true, false, t, f").arg("true")+"\n");
 2740     }
 2741 
 2742     if(!lastWarning.isEmpty())
 2743         lastWarning.insert(0,Import::tr("Notes:")+"\n");
 2744     if(count>0)
 2745         lastWarning.insert(0,Import::tr("%1 container activities (%2 total activities) added. Please check activities form.").arg(count).arg(count2)+"\n");
 2746 
 2747     QDialog* newParent3=new LastWarningsDialog(newParent);
 2748     //DON'T ADD THIS! newParent3->deleteLater();
 2749     newParent=newParent3;
 2750     LastWarningsDialog& lwd=(*((LastWarningsDialog*)newParent));
 2751     int w=chooseWidth(lwd.sizeHint().width());
 2752     int h=chooseHeight(lwd.sizeHint().height());
 2753     lwd.resize(w,h);
 2754     centerWidgetOnScreen(&lwd);
 2755 
 2756     ok=lwd.exec();
 2757 
 2758     int tmp=fileName.lastIndexOf(FILE_SEP);
 2759     IMPORT_DIRECTORY=fileName.left(tmp);
 2760     //gt.rules.internalStructureComputed=false;
 2761 }