1 /* ---------------------------------- functions.cpp ---------------------------------------------------------------------------
2 file containing all functions for luckybackupwindow
3 
4 ===============================================================================================================================
5 ===============================================================================================================================
6     This file is part of "luckyBackup" project
7     Copyright, Loukas Avgeriou
8     luckyBackup is distributed under the terms of the GNU General Public License
9     luckyBackup is free software: you can redistribute it and/or modify
10     it under the terms of the GNU General Public License as published by
11     the Free Software Foundation, either version 3 of the License, or
12     (at your option) any later version.
13 
14     luckyBackup is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17     GNU General Public License for more details.
18 
19     You should have received a copy of the GNU General Public License
20     along with luckyBackup.  If not, see <http://www.gnu.org/licenses/>.
21 
22 project version	: Please see "main.cpp" for project version
23 
24 developer          : luckyb
25 last modified      : 22 May 2016
26 ===============================================================================================================================
27 ===============================================================================================================================
28 */
29 
30 #include <QTextStream>
31 #include <QToolBar>
32 
33 #include "global.h"
34 #include "luckybackupwindow.h"
35 #include "operationClass.h"
36 #include "textDialog.h"
37 
38 // InitializeVariables =============================================================================================================================
39 // variables initialization
InitializeVariables()40 void luckyBackupWindow::InitializeVariables()
41 {
42     TotalOperations = 0;
43     currentOperation=-1;
44     NOWexecuting = false;
45     guiModeNormal = true;
46     modifyOK = false;
47     savedProfile = true;
48     taskClicked = false;
49     taskChanged = false;
50     GoBack = false;
51     InfoData = "";
52     InfoInt = 0;
53     defaultLanguage = "en";
54     mainWindowWidth = 615;
55     mainWindowHeight = 500;
56     AreToolbarsLocked = true;
57     IsVisibleProfileComboToolbar = true;
58     IsVisibleProfileToolbar = true;
59     IsVisibleProfileStartToolbar = true;
60     IsVisibleToolbarText = false;
61     IsVisibleInfoWindow = true;
62     validation = false;
63     deletedTaskNames.clear();
64     saveOrNot = true;
65     manualChapter = "";
66     showOnlyErrors = false;
67 
68     // Running desktop environment
69     // kde
70     char *isKDE = getenv("KDE_FULL_SESSION");
71     if (QString(isKDE) != "")
72         KDErunning = true;
73     else
74         KDErunning = false;
75     // if LB is run using kdesu the environmental variable does not work
76     // so we will check if kdesud is running as a process...
77     // It is commented because the super use cannot use eg the tray notification anyway, so he/she will use the qt stuff
78     /*if (currentUser == "super user")
79     {
80         QProcess *kdesuProcess;    kdesuProcess = new QProcess(this);
81         QStringList kdesuArgs;     kdesuArgs << "-c" << "ps aux | grep kdesud";
82         kdesuProcess -> start ("/bin/sh",kdesuArgs);
83         kdesuProcess -> waitForFinished();
84         if (kdesuProcess -> exitCode() == 0)        // there is a root process "kdesu_stub running
85             KDErunning = true;
86     }*/
87 
88     // gnome
89     char *isGnome = getenv("DESKTOP_SESSION");
90     if ((QString(isGnome) == "gnome") || (QString(isGnome) == "GNOME"))
91         GNOMErunning = true;
92     else
93         GNOMErunning = true;
94 
95     // translations --------------------------------
96     TransDir = "";
97     transDir.setPath(relativeTransDir);
98     QStringList transContQm = transDir.entryList ( QStringList("luckybackup*.qm"), QDir::Files, QDir::NoSort); // list of .qm files inside transdir
99     if ( (transDir.exists()) && (!transContQm.isEmpty()) )
100         TransDir = transDir.absolutePath();
101     else
102     {
103         transDir.setPath(systemTransDir);
104         TransDir = transDir.absolutePath();
105     }
106 
107     // manual actual path (QUrl helpURL) --------------------------------
108     helpURL.setScheme("file");
109     helpURL.setUrl("Does_not_exist");
110     QFile manual;
111     manual.setFileName(suseManual);
112     if (manual.exists())	//if the manual is located in /usr/share/doc/packages/luckybackup (normal installation) - openSuse
113         helpURL.setUrl(suseManual);
114     manual.setFileName(systemManual);
115     if (manual.exists())	//if the manual is located in /usr/share/doc/luckybackup (normal installation)
116         helpURL.setUrl(systemManual);
117     manual.setFileName(relativeManual);
118     if (manual.exists())	//if the manual is located in relative path manual/ (app run from commandline)
119         helpURL.setUrl(QApplication::applicationDirPath() + SLASH + relativeManual);
120 
121     // licence actual path (QUrllicenseURL) --------------------------------------------------------
122     licenseURL.setScheme("file");
123     licenseURL.setUrl("Does_not_exist");
124     QFile license;
125     license.setFileName(debianLicense);
126     if (license.exists())	//if the licence file is located in the normal debian directory
127         licenseURL.setUrl(debianLicense);
128     license.setFileName(suseLicense);
129     if (license.exists())	//if the licence file is located in the normal suse directory
130         licenseURL.setUrl(suseLicense);
131     license.setFileName(systemLicense);
132     if (license.exists())	//if the licence file is located in the normal installation directory
133         licenseURL.setUrl(systemLicense);
134     license.setFileName(relativeLicense);
135     if (license.exists())	//if the licence file is located in the same directory (compile directory)
136         licenseURL.setUrl(relativeLicense);
137 
138     // fix OS/2 & win compatibility issues
139     if (notXnixRunning)
140     {
141         licenseURL.setUrl("Does_not_exist");
142         helpURL.setUrl("Does_not_exist");
143 
144         QString OS2manual = relativeManual;     OS2manual.replace("/",SLASH);    OS2manual = OS2manual.toLower();
145         QString OS2license = relativeLicense;   OS2license.replace("/",SLASH);   OS2license= OS2license.toLower();
146 
147         manual.setFileName(OS2manual);    license.setFileName(OS2license);
148         if (manual.exists())
149             helpURL.setUrl(OS2manual);
150         if (license.exists())
151             licenseURL.setUrl(OS2license);
152 
153         myHome.replace("/",SLASH);
154         luckyBackupDir.replace("/",SLASH);
155         settingsFile.replace("/",SLASH);
156         profileDir.replace("/",SLASH);
157         defaultProfile.replace("/",SLASH);
158         defaultProfile.replace("/",SLASH);
159         standardDefaultProfile.replace("/",SLASH);
160         logDir.replace("/",SLASH);
161         logfilename.replace("/",SLASH);
162         snapDefaultDir.replace("/",SLASH);
163         snapChangesDir.replace("/",SLASH);
164         snapEmptyDir.replace("/",SLASH);
165         snapchangesfilename.replace("/",SLASH);
166         scheduleDir.replace("/",SLASH);
167         schedulefilename.replace("/",SLASH);
168         cronfilename.replace("/",SLASH);
169         relativeTransDir.replace("/",SLASH);
170         systemTransDir.replace("/",SLASH);
171     }
172 }
173 
174 
175 // retranslateUi ===================================================================================================================================
176 // retranslate the ui every time the user chooses a different language from the menu
retranslateUi()177 void luckyBackupWindow::retranslateUi()
178 {
179     ui.menuFile 		-> setTitle(tr("&Profile","This is a top menu item"));
180     ui.actionRefresh	-> setText(tr("&Refresh","This is a top 'Profile' menu action"));
181     ui.actionDefault	-> setText(tr("De&fault","This is a top 'Profile' menu action"));
182     ui.actionDefault	-> setToolTip(tr("Set as Default","This is a top 'Profile' menu action tooltip"));
183     ui.actionDescription	-> setText(tr("&View/Edit Description","This is a top 'Profile' menu action"));
184     ui.actionDescription	-> setToolTip(tr("View/Edit the profile description","This is a top 'Profile' menu action tooltip"));
185     ui.actionRename		-> setText(tr("R&ename","This is a top 'Profile' menu action"));
186     ui.actionDelete		-> setText(tr("&Delete","This is a top 'Profile' menu action"));
187     ui.actionNew 		-> setText(tr("&New","This is a top 'Profile' menu action"));
188     ui.actionSave 		-> setText(tr("&Save","This is a top 'Profile' menu action"));
189     ui.actionExport		-> setText(tr("E&xport","This is a top 'Profile' menu action"));
190     ui.actionImport		-> setText(tr("&Import","This is a top 'Profile' menu action"));
191     ui.actionSchedule 	-> setText(tr("S&chedule","This is a top 'Profile' menu action"));
192     ui.actionEmail      -> setText(tr("E&mail","This is a top 'Profile' menu action"));
193     ui.actionEmail      -> setToolTip(tr("Email report after profile execution","This is a top 'Profile' menu action tooltip"));
194     ui.actionQuit 		-> setText(tr("&Quit","This is a top 'Profile' menu action"));
195     ui.actionDuplicate_Profile -> setText(tr("D&uplicate","This is a top 'Profile' menu action"));
196 
197     ui.menu_Task		-> setTitle(tr("&Task","This is a top menu action"));
198     ui.action_TaskAdd	-> setText(tr("&Add","This is a top 'Task' menu action"));
199     ui.action_TaskRemove	-> setText(tr("&Remove","This is a top 'Task' menu action"));
200     ui.action_TaskModify	-> setText(tr("&Modify","This is a top 'Task' menu action"));
201     ui.action_TaskDuplicate	-> setText(tr("Create D&uplicate task","This is a top 'Task' menu action"));
202     ui.action_TaskCreateRestore -> setText(tr("Create R&estore task","This is a top 'Task' menu action"));
203     ui.action_TaskManageBackup -> setText(tr("Manage &Backup","This is a top 'Task' menu action"));
204     ui.action_TaskManageBackup -> setToolTip(tr("display - restore - delete existing backups of highlighted task",
205                             "This is a top 'Task' menu action tooltip"));
206 
207     settingsMenu	    -> setTitle(tr("&Settings","This is a top menu item"));
208     visibleProfileToolbar-> setText(tr("Actions","This is a top menu action"));
209     visibleProfileComboToolbar -> setText(tr("Current Profile","This is a top menu action"));
210     actionLockToolbars  -> setText(tr("Lock","This is a top menu action. Refers to toolbars"));
211     actionVisibleToolbarText -> setText(tr("Show text under icons","This is a top menu action"));
212     languageMenu	    -> setTitle(tr("&Language","This is a top menu item"));
213     toolbarsMenu	    -> setTitle(tr("&Toolbars","This is a top menu item"));
214 
215     if (WINrunning)
216     {
217         actionSetWinPaths -> setText(tr("Set paths","This is a top menu action"));
218         actionSetWinPaths -> setToolTip(tr("Set paths for rsync and ssh commands","This is a top menu action tooltip"));
219     }
220 
221     helpMenu	        -> setTitle(tr("&Help","This is a top menu item"));
222     actionHelp	        -> setText(appName + " " + tr("&Handbook","full phrase: 'luckyBackup Handbook'"));
223     actionAbout         -> setText(tr("&About","full phrase: 'about luckyBackup'") + " " + appName);
224 
225     ui.comboBox_profile -> setToolTip(tr("current profile"));
226 
227     ui.label_TaskList   -> setText(tr("Task list","task list label"));
228     ui.label_include    -> setText(tr("include","label of 'include' checkboxes"));
229     ui.frame_operations -> setToolTip(tr("List of all the available tasks","task list tooltip - line1")+"\n"+
230                 tr("Use the 'include checkboxes' to include or not a selected task","task list tooltip - line2"));
231     ui.pushButton_up -> setToolTip(tr("Move the highlighted task up, by one position","button tooltip"));
232     ui.pushButton_down -> setToolTip(tr("Move the highlighted task down, by one position","button tooltip"));
233     ui.pushButton_nextError	-> setToolTip(tr("jump to next error","button tooltip"));
234     ui.pushButton_previousError	-> setToolTip(tr("jump to previous error","button tooltip"));
235     ui.checkBox_onlyShowErrors -> setText (tr("quiet mode"));
236     ui.checkBox_onlyShowErrors -> setToolTip (tr("Only show errors and important messages during window update"));
237 
238     ui.groupBox_task -> setTitle(tr("Task","task groupbox (add, remove, modify buttons) label"));
239     ui.pushButton_add -> setText(tr("add","add task button label"));
240     ui.pushButton_add -> setToolTip(tr("add task","add task button tooltip"));
241     ui.pushButton_remove -> setText(tr("remove","remove task button label"));
242     ui.pushButton_remove -> setToolTip(tr("remove highlighted task","remove task button tooltip"));
243     ui.pushButton_edit -> setText(tr("modify","modify task button label"));
244     ui.pushButton_edit -> setToolTip(tr("modify highlighted task","modify task button tooltip"));
245 
246     //ui.groupBox_operations -> setTitle(tr("Run","run groupbox label"));
247     ui.pushButton_start -> setText(tr("Run","start button label"));
248     ui.pushButton_start -> setToolTip(tr("Begin the execution of all included tasks","start button tooltip"));
249     ui.AbortButton  -> setText(tr("Abort","Abort button label"));
250     ui.AbortButton -> setToolTip(tr("Stop the execution of running tasks NOW","Abort button tooltip"));
251     ui.DoneButton -> setText (tr("Done"));
252     ui.DoneButton -> setToolTip(tr("Execution of tasks finished","Done button tooltip"));
253     ui.checkBox_DryRun -> setText(tr("Dry","simulation checkbox label. Translate this as 'simulation'"));
254     ui.checkBox_DryRun -> setToolTip(tr("This will perform a <b>simulation run</b> that doesn't make any changes (and produces mostly the same output as a real run)","simulation checkbox tooltip - line1. Please leave tags <b> and </b> intact and surrounding 'simulation run'")+".<br>"+tr("NOTE","simulation checkbox tooltip - line2")+": "+tr("Progressbar update will not be realistic","simulation checkbox tooltip - line2"));
255 
256     ui.pushButton_shutdown -> setText(tr("shutdown","shutdown button label"));
257     ui.pushButton_shutdown -> setToolTip(tr("Press down to shutdown the system when done","shutdown button tooltip"));
258 
259     ui.label_InformationWindow -> setText(tr("Information window","information window title"));
260     ui.pushButton_exit -> setToolTip(tr("Exit","exit button tooltip. full phrase is: 'exit luckybackup'")+" "+appName);
261     ui.pushButton_exit -> setText(tr("EXIT","EXIT button label"));
262     if (IsVisibleInfoWindow)
263         ui.pushButton_InfoCollapse -> setToolTip(tr("Hide information window","show/hide information window button tooltip"));
264     else
265         ui.pushButton_InfoCollapse -> setToolTip(tr("Show information window","show/hide information window button tooltip"));
266 
267     ui.pushButton_minimizeToTray -> setText(tr("minimize to tray"));
268     ui.pushButton_minimizeToTray -> setToolTip(tr("minimizes the window to the tray area"));
269 }
270 
271 // createProfileCombo =============================================================================================================================
272 // fill the profile combo box with existing profiles.
273 // Also sets the currentProfileIndex to the index of the current profile
274 // Executes when the app starts & when the list of profiles in ~/.luckybackup/profiles changes
createProfileCombo()275 void luckyBackupWindow::createProfileCombo()
276 {
277     GoBack = true;	// the next line will execute function setCurrentProfile. set true to avoid that
278     ui.comboBox_profile -> clear();
279     int currentProfileIndex = -1;
280     QDir profiledir(profileDir);
281     profiledir.setFilter(QDir::AllEntries | QDir::Hidden | QDir::NoDotAndDotDot);
282     profiledir.setSorting(QDir::Name | QDir::LocaleAware);
283     QStringList profileNames = profiledir.entryList(QStringList("*.profile"));
284 
285     QString profilename="";
286     for (count = 0; count < profileNames.size(); ++count)
287     {
288         profilename = profileNames[count];
289         if (currentProfile == profileDir + profilename)	// set the currentProfileIndex to the index of the current profile
290             currentProfileIndex = count;
291 
292         profilename.chop(8);
293 
294         GoBack = true;	// the next line will execute function setCurrentProfile. set true to avoid that
295         ui.comboBox_profile -> addItem (profilename);
296     }
297     if (currentProfileIndex == -1)	// if no default profile exists
298         currentProfileIndex = 0;
299 
300     GoBack = true;	// the next line will execute function setCurrentProfile. set true to avoid that
301     ui.comboBox_profile -> setCurrentIndex(currentProfileIndex);
302     GoBack = false;
303 
304 }
305 
306 // createActions =============================================================================================================================
307 // create all main action
createActions()308 void luckyBackupWindow::createActions()
309 {
310     actionHelp = new QAction(QIcon(":/luckyPrefix/book.png"), "Handbook", this);
311     actionHelp -> setShortcut(tr("F1"));
312     actionAbout = new QAction(QIcon(":/luckyPrefix/about.png"), "About", this);
313 
314     actionLockToolbars = new QAction("Lock Toolbars",this);
315     actionLockToolbars -> setCheckable(true);
316     actionLockToolbars -> setChecked(AreToolbarsLocked);
317     actionVisibleToolbarText = new QAction("Labels under icons",this);
318     actionVisibleToolbarText -> setCheckable(true);
319     actionVisibleToolbarText -> setChecked(IsVisibleToolbarText);
320 
321     if (WINrunning)
322     {
323         actionSetWinPaths = new QAction("Set paths",this);
324         connect( actionSetWinPaths, SIGNAL(triggered()), this, SLOT(setWinPaths()));      //menu action set paths
325     }
326 
327     connect( actionHelp, SIGNAL(triggered()), this, SLOT(help()));		//menu action help
328     connect( actionAbout, SIGNAL(triggered()), this, SLOT(about()));	//menu action about
329     connect( actionLockToolbars, SIGNAL(triggered()), this, SLOT(setToolbarAttrs()));	//menu action lock toolbars
330     connect( actionVisibleToolbarText, SIGNAL(triggered()), this, SLOT(setToolbarAttrs()));	//menu action visible toolbar text
331 }
332 
333 // createMenus =============================================================================================================================
334 // create the main window menus
createMenus()335 void luckyBackupWindow::createMenus()
336 {
337     // settings menu ----------------------------------------------------------------------------------
338     settingsMenu = menuBar() -> addMenu("Settings");
339 
340     // help menu ----------------------------------------------------------------------------------
341     helpMenu = menuBar() -> addMenu("Help");
342     helpMenu -> addAction(actionHelp);
343     helpMenu -> addSeparator();
344     helpMenu -> addAction(actionAbout);
345 
346     // toolbars actions -------------------------------------------------------------------------------
347     toolbarsGroup = new QActionGroup(this);
348     toolbarsMenu = settingsMenu -> addMenu("");
349 
350     visibleProfileComboToolbar = profileComboToolbar->toggleViewAction();
351     toolbarsMenu -> addAction(visibleProfileComboToolbar);
352     visibleProfileToolbar = profileToolbar->toggleViewAction();
353     toolbarsMenu -> addAction(visibleProfileToolbar);
354     toolbarsMenu -> addSeparator();
355     toolbarsMenu -> addAction(actionLockToolbars);
356     toolbarsMenu -> addAction(actionVisibleToolbarText);
357     settingsMenu -> addSeparator();
358 
359     // language sub-menu -------------------------------------------------------------------------------
360     languageGroup = new QActionGroup(this);
361     languageMenu = settingsMenu -> addMenu("");
362     connect(languageGroup, SIGNAL(triggered(QAction *)), this, SLOT( setLanguage( QAction *) )  );
363 
364     QStringList fileNames = transDir.entryList(QStringList("luckybackup_*.qm"));
365     for (count = 0; count < fileNames.size(); ++count)
366     {
367         QString currentLocale = fileNames[count];
368         currentLocale.remove(0, currentLocale.indexOf('_') + 1);
369         currentLocale.chop(3);
370 
371         QTranslator translator;
372         translator.load(fileNames[count], TransDir);
373         QString language = translator.translate("luckyBackupWindow","English");
374 
375         action = new QAction(tr("&%1 %2").arg(count + 1).arg(language), this);
376         action -> setCheckable(true);
377         action -> setData(currentLocale);
378 
379         languageMenu -> addAction(action);
380         languageGroup -> addAction(action);
381 
382         if (currentLocale == defaultLanguage)
383         {
384             action->setChecked(true);
385             setLanguage(action);
386         }
387     }
388 
389     // Win-OS2 paths sub-menu -------------------------------------------------------------------------------
390     if (WINrunning)
391         settingsMenu -> addAction(actionSetWinPaths);
392 }
393 // createToolbar =============================================================================================================================
394 // create the tool bars
createToolbar()395 void luckyBackupWindow::createToolbar()
396 {
397     profileComboToolbar = new QToolBar("current profile", this);
398     profileToolbar = new QToolBar("actions", this);
399     profileStartToolbar = new QToolBar("start", this);
400     shutdownToolbar = new QToolBar("shutdown", this);
401     errorsToolbar = new QToolBar("errors", this);
402 
403     this -> addToolBar(Qt::TopToolBarArea, profileComboToolbar);
404     this -> addToolBar(Qt::TopToolBarArea, profileToolbar);
405     this -> addToolBar(Qt::TopToolBarArea, shutdownToolbar);
406     this -> addToolBar(Qt::TopToolBarArea, errorsToolbar);
407     this -> addToolBar(Qt::TopToolBarArea, profileStartToolbar);
408 
409     QSize ToolbarIconSize(22,22);
410     profileToolbar -> setIconSize(ToolbarIconSize);
411 
412     //Profile-------------------------------------------------------------------
413     profileComboToolbar -> addWidget(ui.comboBox_profile);	//profile drop-down list
414 
415     //Start & simulation buttons-------------------------------------------------------------------
416     profileStartToolbar -> addWidget(ui.groupBox_operations);//profile start toolbar
417 
418     //shutdown system button-------------------------------------------------------------------
419     shutdownToolbar     -> addWidget(ui.pushButton_shutdown);//shutdown system toolbar
420 
421     // prev/next error buttons-------------------------------------------------------------------
422     errorsToolbar     -> addWidget(ui.pushButton_previousError);    // errors toolbar
423     errorsToolbar     -> addWidget(ui.pushButton_nextError);
424     errorsToolbar     -> addWidget(ui.checkBox_onlyShowErrors);
425 
426     //Profile Actions-------------------------------------------------------------------
427     profileToolbar -> addSeparator();			//---seperator---
428     profileToolbar -> addAction(ui.actionSave);		//save
429 //	profileToolbar -> addAction(ui.actionDefault);		//default
430 //	profileToolbar -> addAction(ui.actionRename);		//rename
431     profileToolbar -> addAction(ui.actionNew);		//new
432     profileToolbar -> addAction(ui.actionDelete);		//delete
433 //	profileToolbar -> addSeparator();
434 //	profileToolbar -> addAction(ui.actionExport);
435 //	profileToolbar -> addAction(ui.actionImport);
436     profileToolbar -> addSeparator();			//---seperator---
437     profileToolbar -> addAction(ui.actionSchedule);		//schedule
438     profileToolbar -> addAction(ui.actionEmail);     //email report
439     profileToolbar -> addAction(ui.actionRefresh);		//refresh
440     profileToolbar -> addSeparator();			//---seperator---
441     profileToolbar -> addAction(ui.actionQuit);		//quit
442     profileToolbar -> addSeparator();			//---seperator---
443 
444     profileComboToolbar -> setVisible (IsVisibleProfileComboToolbar);
445     profileToolbar -> setVisible (IsVisibleProfileToolbar);
446 
447     setToolbarAttrs();
448 }
449 
450 
451 
452 // checkOperationsList===============================================================================================================================
453 // Checks if the Operations list is ok to proceed
454 // calls global function checkTaskList()
checkOperationList()455 bool luckyBackupWindow::checkOperationList()
456 {
457     bool showBox = checkTaskList();
458 
459     if (ask)
460     {
461         message.prepend("<font color=red><b>" + tr("ERROR") + "</b></font><br>");
462         if (showBox)
463         {
464             textDialog textdialogC ("QtCritical", message, this);
465             textdialogC.exec();
466         }
467 
468         ui.textBrowser_info -> setText(message);
469         return false;
470     }
471     return true;
472 }
473 
474 //checkDeclared ===================================================================================================================================
475 //Check if the declared data are ok by calling checkBackupDirs, checkSyncDirs accordingly
476 //This is called from the gui
checkDeclared()477 void luckyBackupWindow::checkDeclared()
478 {
479     int currentSelection = ui.listWidget_operations -> currentRow();	//keep the current selection
480     checkDeclaredDirs(true);
481 
482     currentOperation = 0;
483     CheckedData = "";
484     CheckedDataCLI = "";
485     while (currentOperation < TotalOperations)
486     {
487         ui.listWidget_operations -> setCurrentRow(currentOperation);
488         if (Operation[currentOperation] -> GetIncluded())	//if the operations is "included"
489         {
490             if (Operation[currentOperation] -> GetOK())
491                 ui.listWidget_operations -> currentItem() -> setIcon(QIcon(":/luckyPrefix/okay.png"));
492             if (Operation[currentOperation] -> GetWARNING())
493                 ui.listWidget_operations -> currentItem() -> setIcon(QIcon(":/luckyPrefix/cancel.png"));
494             if (Operation[currentOperation] -> GetCRITICAL())
495                 ui.listWidget_operations -> currentItem() -> setIcon(QIcon(":/luckyPrefix/warning.png"));
496             if (Operation[currentOperation] -> GetSourcePerms())
497                 ui.listWidget_operations -> currentItem() -> setIcon(QIcon(":/luckyPrefix/cancel.png"));
498             if (Operation[currentOperation] -> GetDestPerms())
499                 ui.listWidget_operations -> currentItem() -> setIcon(QIcon(":/luckyPrefix/cancel.png"));
500         }
501         else
502             ui.listWidget_operations -> currentItem() -> setIcon(QIcon(":/luckyPrefix/about.png"));
503         currentOperation++;
504     }
505 
506     if (currentSelection > -1)		// re-select the current selection (don't leave the last task selected)
507     {
508         currentOperation = currentSelection;
509         ui.listWidget_operations -> setCurrentRow(currentOperation);
510     }
511 }
512 
513 // setCurrentprofile ================================================================================================================================
514 // function to set the currentProfile
setCurrentProfile(QString currentProfileSet)515 void luckyBackupWindow::setCurrentProfile(QString currentProfileSet)
516 {
517     if (notXnixRunning) // if OS2 or win is running and by mistake the path includes "/" instead of "\"
518         currentProfileSet.replace("/",SLASH);
519 
520     //current profile full absolut path
521     currentProfile = currentProfileSet;
522 
523     //current profile QFile
524     profile.setFileName(currentProfile);
525 
526     //current profile's name (QString)
527     profileName = currentProfile;
528     profileName = profileName.right(profileName.size() - profileName.lastIndexOf(SLASH) - 1);
529     profileName.chop(8);
530 }
531 
532 // loadCurrentprofile ================================================================================================================================
533 // function to load the current profile
534 // calls global function loadProfile
loadCurrentProfile()535 bool luckyBackupWindow::loadCurrentProfile()
536 {
537     loadData = "";
538     // Initialize arrays & window to zero values first
539     ui.listWidget_operations -> clear();	//clear the operations list
540     TotalOperations = 0;	//Set the operations list size to 0
541     //taskAvailable -> ;					//clear operations array ?????????
542 
543     if (currentProfile == defaultProfile)
544         loadData.append("<font color=blue><b>" + tr("loading default profile ...","information window message") + "</font></b><br>");
545     else
546         loadData.append("<font color=blue><b>" + tr("loading profile ...","information window message") + "</font></b><br>");
547 
548     int loadOK = loadProfile(currentProfile);	// try to load the currentProfile
549     if (loadOK == 1)		// if it cannot open
550     {
551         loadData.append("<font color=red><b>" + tr("loading failed","information window message") + "</font></b><br>" +
552                 tr("Unable to open profile","information window message. full phrase is 'Unable to open profile <PROFIENAME>'")+" <b>" + profileName + "</b><br><font color=red>"
553                 + profile.errorString()) +"</font>";
554         return false;					//do nothing more
555     }
556 
557     if (loadOK == 2)			// if it is not a valid profile
558     {
559         loadData.append("<font color=red><b>" + tr("loading failed","information window message") + "</font></b><br>" +
560         tr("profile ","information window message. Full phrase is: 'profile <PROFILENAME> is not valid for luckybackup version:X.Y'. BEWARE of the whitespace in the end")
561         + "<b>" + profileName + "</b> " + tr("is not valid for","information window message. Full phrase is: 'profile <PROFILENAME> is not valid for luckybackup version:X.Y") + " " + appName +", "+ tr("version:","information window message. Full phrase is: 'profile <PROFILENAME> is not valid for luckybackup version:X.Y") + countStr.setNum(appVersion));
562         return false;	//do nothing more
563     }
564 
565     // if all went ok (profile loaded) - loadOK == 0
566     savedProfile = true;
567     ui.actionSave -> setEnabled(false);
568     currentOperation = 0;
569     while (currentOperation < TotalOperations)	// fill in the task list
570     {
571         ui.listWidget_operations -> addItem( Operation[currentOperation] -> GetName() );
572         ui.listWidget_operations -> setCurrentRow(currentOperation);
573         if (Operation[currentOperation] -> GetIncluded())
574             ui.listWidget_operations -> currentItem() -> setCheckState (Qt::Checked);
575         else
576             ui.listWidget_operations -> currentItem() -> setCheckState (Qt::Unchecked);
577         currentOperation++;
578     }
579 
580     TotalOperations = ui.listWidget_operations -> count();	//Get the Operations list size
581     checkDeclared();					// Check tasks & set icons
582     loadData.append(tr("profile","info window message. full phrase: 'profile <PROFILENAME> loaded successfully'") + " <b>" + profileName + "</b> <font color=green>" + tr("loaded successfully","info window message. full phrase: 'profile <PROFILENAME> loaded successfully'") + " !!</font>");
583     ui.listWidget_operations -> setSpacing(1);
584 
585     // Check to see if this profile is scheduled and inform user  ~~~~~~~~
586     QString CronTab = "";
587     QString profileCheckCron = profileName;
588     profileCheckCron = profileCheckCron.replace(" ","\\ ");
589     QFile cronFile (cronfilename);
590     if (cronFile.open(QIODevice::ReadOnly | QIODevice::Text))		//open the cronFile
591     {
592         loadData.append("<br>"+tr("scheduled","this refers to a profile") + ": <b>");
593         QTextStream in(&cronFile);
594         while (!in.atEnd())
595             CronTab.append(in.readLine());
596         if (CronTab.contains(profileCheckCron, Qt::CaseInsensitive))
597             loadData.append(tr("YES") + "</b>");
598         else
599             loadData.append(tr("NO") + "</b>");
600     }
601 
602     //append the profile description if it exists
603     if (profileDescription != "")
604     {
605         QString profileDescriptionDisplay = profileDescription;
606         profileDescriptionDisplay.replace("\n","<br>");
607         loadData.append("<br><br><b>" + tr("Description") + ":</b><br>" + profileDescriptionDisplay);
608     }
609 
610     // Append a general directions message if the profile is empty
611     if ( TotalOperations == 0 )
612         loadData.append("<br><font color=magenta>" + tr("The task list is empty")+ "<br><b>" + tr("Use the \"add\" button on the right to get started","Please keep the add word inside quotes") + "</b></font><br>");
613 
614     return true;	//profile loaded successfully
615 }
616 
617 // saveCurrentprofile ===============================================================================================================================
618 // function to save the current profile
619 // calls global function saveProfile()
saveCurrentProfile()620 bool luckyBackupWindow::saveCurrentProfile()
621 {
622     saveData = "";
623     TotalOperations = ui.listWidget_operations -> count();	//Get the Operations list size
624 
625     if (currentProfile == defaultProfile)
626         saveData.append("<font color=blue><b>" + tr("saving default profile ...","Information window message") + "</font></b><br>");
627     else
628         saveData.append("<font color=blue><b>" + tr("saving profile ...","Information window message") + "</font></b><br>");
629 
630     if (!saveProfile(currentProfile))
631     {
632         saveData.append("<font color=red><b>" + tr("WARNING") + "</b></font><br>");
633         if (currentProfile == defaultProfile)
634             saveData.append(tr("default profile","Information window message. Full phrase: 'default profile <PROFILENAME> could not be saved'."));
635         else
636             saveData.append(tr("profile","Information window message. Full phrase: 'profile <PROFILENAME> could not be saved'"));
637 
638         saveData.append(" <b>" + profileName + "</b> "+ tr("could not be saved","Information window message. Full phrase: '(default) profile <PROFILENAME> could not be saved'") + "<br>" +	"<font color=red>"+ profile.errorString() + "</font>");
639         savedProfile = false;
640         ui.actionSave -> setEnabled(true);
641         return false;
642     }
643 
644     saveData.append(tr("profile","Information window message. Full phrase: 'profile <PROFILENAME> saved successfully'") + " <b>" + profileName + "</b> <font color=green>" + tr("saved successfully","Information window message. Full phrase: 'profile <PROFILENAME> saved successfully'") + " !!</font>");
645 
646     // Check to see if this profile is scheduled and inform user  ~~~~~~~~
647     QString CronTab = "";
648     QFile cronFile (cronfilename);
649     if (cronFile.open(QIODevice::ReadOnly | QIODevice::Text))		//open the cronFile
650     {
651         saveData.append("<br>"+tr("scheduled","this refers to a profile") + ": <b>");
652         QTextStream in(&cronFile);
653         while (!in.atEnd())
654             CronTab.append(in.readLine());
655         if (CronTab.contains(profileName, Qt::CaseInsensitive))
656             saveData.append(tr("YES") + "</b>");
657         else
658             saveData.append(tr("NO") + "</b>");
659     }
660 
661     //append the profile description if it exists
662     if (profileDescription != "")
663     {
664         QString profileDescriptionDisplay = profileDescription;
665         profileDescriptionDisplay.replace("\n","<br>");
666         loadData.append("<br><br><b>" + tr("Description") + ":</b><br>" + profileDescriptionDisplay );
667     }
668 
669     // if some tasks were deleted also delete the relevant .changes and log files
670     for (int count = 0; count < deletedTaskNames.size(); ++count)
671         arrangeLogSnap(0,"delete",deletedTaskNames.at(count));
672     deletedTaskNames.clear();
673 
674     savedProfile = true;			//change profile status to "saved"
675     ui.actionSave -> setEnabled(false);
676 
677     return true;
678 }
679 
680 // createCurrentprofile ===============================================================================================================================
681 // function to create the current profile with an empty task list
682 // calls global function saveProfile()
createCurrentProfile()683 int luckyBackupWindow::createCurrentProfile()
684 {
685     createData = "";
686     if (!profile.exists())			//if the currentProfile does not exist, try to create it
687     {
688         TotalOperations = 0;	//Set the Operations list size to 0
689 
690         //Set email default options
691         emailNever = 1;
692         emailSubject = emailDefaultSubject;
693         emailBody = emailDefaultBody;
694 
695         if (currentProfile == defaultProfile)
696             createData.append("<font color=blue><b>" + tr("creating default profile ...","Information window message") + "</font></b><br>");
697         else
698             createData.append("<font color=blue><b>" + tr("creating profile ...","Information window message") + "</font></b><br>");
699 
700         if (!saveProfile(currentProfile))	//if the profile cannot be created
701         {
702             createData.append("<font color=red><b>" + tr("WARNING") + "</b></font><br>");
703             if (currentProfile == defaultProfile)
704                 createData.append(tr("default profile","Information window message. Full phrase: 'default profile <PROFILENAME> could not be created'."));
705             else
706                 createData.append(tr("profile","Information window message. Full phrase: 'profile <PROFILENAME> could not be created'."));
707             createData.append(" <b>" + profileName + "</b> "+ tr("could not be created","Information window message. Full phrase: '(default) profile <PROFILENAME> could not be created'") + "<br>" + "<font color=red>"+ profile.errorString() + "</font>");
708             return 2;	//profile could not be created
709         }
710 
711         createData.append(tr("profile","Information window message. Full phrase: 'profile <PROFILENAME> created successfully'") + " <b>" + profileName + "</b> <font color=green>" + tr("created successfully","Information window message. Full phrase: 'profile <PROFILENAME> created successfully'") + " !!</font>");
712         createData.append("<br><font color=magenta>" + tr("Use the \"add\" button on the right to get started","Please keep the add word inside quotes") + "</font><br>");
713         createProfileCombo();	// update the profile combobox with all existing profiles
714         savedProfile = true;			//change profile status to "saved"
715         ui.actionSave -> setEnabled(false);
716         return 1;		// Profile created successfully
717     }
718     return 0;	// profile already exists, just proceed
719 }
720 
721 // isProfileSaved ====================================================================================================================================
722 //function to check if the current profile is saved and proceed or not
isProfileSaved()723 int luckyBackupWindow::isProfileSaved()
724 {
725     if (!savedProfile)	//if the current profile is not saved, ask the user if he/she wants to, before proceeding
726     {
727         textDialog textdialogQ ("QtQuestion",
728                     tr("Profile","Question dialog message. Full phrase: 'profile <PROFILENAME> is modified'")+" <b>" + profileName + "</b> " +
729                     tr("is modified","Question dialog message. Full phrase: 'profile <PROFILENAME> is modified'")+ ".<br><br>" +
730                     tr("Would you like to save it before proceeding ?"), this);
731         textdialogQ.exec();
732 
733         if (textdialogQ.getGoOn() > 0)		//if user answers yes
734         {
735             if (!saveCurrentProfile())	// if it cannot be saved for any reason pop up a yes/no message box to go on or not
736             {
737                 textDialog textdialogQ2 ("QtQuestion",
738                     tr("Profile","Question dialog message. Full phrase: 'profile <PROFILENAME> could not be saved'")+" <b>" + profileName + "</b> " +tr("could not be saved","Question dialog message. Full phrase: 'profile <PROFILENAME> could not be saved'")
739                         +"<br><font color=red>"+ profile.errorString()
740                         + "</font><br><br>" + tr("Would you like to proceed anyway?"), this);
741                 textdialogQ2.exec();
742                 if (textdialogQ2.getGoOn() == 0)		//if user answers no
743                 {
744                     int previousIndex = ui.comboBox_profile -> findText (profileName, Qt::MatchExactly);
745                     GoBack = true;	// the next line will execute  function profileComboChanged again. set true to avoid that
746                     ui.comboBox_profile -> setCurrentIndex(previousIndex);
747                     return 0;	//profile could not be saved, user says DO NOT proceed
748                 }
749                 else
750                     return 4;	//profile could not be saved, user wants to proceed
751             }
752             else
753                 return 2;		//profile save successfully, proceed
754         }
755         else
756             return 3;	//user does not want to save profile, proceed
757     }
758     return 1;	// profile is already saved, just proceed
759 }
760 
761 //saveSettings ===================================================================================================================================
762 //Saves various luckybackup settings such as the default profile (text mode after version 0.4.7)
saveSettings()763 bool luckyBackupWindow::saveSettings()
764 {
765     QFile settingsfile(settingsFile);
766     if (!settingsfile.open(QIODevice::WriteOnly))	// if the settings file cannot be saved (or fails to create)
767     {
768         settingsfile.close();
769         return false;
770     }
771 
772     showOnlyErrors = ui.checkBox_onlyShowErrors -> isChecked();
773     //write arrays to settings file
774     QTextStream out(&settingsfile);
775 
776     out << "***************************** WARNING *****************************\n";
777     out << "Do NOT edit this file directly, unless you REALLY know what you are doing !!\n\n\n";
778 
779     out << "[app_global]\n";
780     out << "appName="                       << appName << "\n";                     //output the application name
781     out << "appVersion="                    << appVersion << "\n";                  //output the application version
782     out << "File_Type="                     << "luckybackup_settings_file" << "\n"; //output the application file type (?)
783 
784     out << "\n[settings_global]\n";
785     out << "Main_window_width="             << mainWindowWidth << "\n";             //output the application main window width in pixels
786     out << "Main_window_height="            << mainWindowHeight << "\n";            //output the application main window height in pixels
787     out << "Are_toolbars_locked="           << AreToolbarsLocked << "\n";           //output the lock state of toolbars
788     out << "Is_combo_toolbar_visible="      << IsVisibleProfileComboToolbar << "\n";//output the visible state of the combo toolbar
789     out << "Is_profile_toolbar_visible="    << IsVisibleProfileToolbar << "\n";     //output the visible state of the profile toolbar
790     out << "Is_toolbarText_visible="        << IsVisibleToolbarText << "\n";        //output the visible state of toolbar text
791     out << "Default_Profile="               << defaultProfile << "\n";              //output the default profile full path
792     out << "Default_Language="              << defaultLanguage << "\n";             //output the default language
793     out << "Visible_info_window="           << IsVisibleInfoWindow << "\n";         //output the visibility state of the info window
794     out << "Quite_mode_output="             << showOnlyErrors << "\n";              //output the quite mode state of the commands output window
795 
796     if (WINrunning)
797     {
798         out << "\n[settings_non_*nix]\n";
799         out << "win_rsync_path="            << rsyncCommandPath << "\n";            //output the rsync path for windows or OS2
800         out << "win_ssh_path="              << sshCommandPath << "\n";              //output the ssh path for windows or OS2
801         out << "cygpath_path="              << cygpathCommand << "\n";
802         out << "dosdev_path="               << dosdevCommand << "\n";
803         out << "vshadowdir_path="           << vshadowDir << "\n";
804         out << "tempdir_path="              << tempDirPath << "\n";
805     }
806 
807     out << "\n[Settings_file_end]" << "\n";
808 
809     settingsfile.close();
810     return true;
811 }
812 
813 //loadSettings ===================================================================================================================================
814 //loads various luckybackup settings such as the default profile (text mode after version 0.4.7)
loadSettings()815 bool luckyBackupWindow::loadSettings()
816 {
817     QFile settingsfile(settingsFile);
818     if (!settingsfile.open(QIODevice::ReadOnly))        //if the settings file cannot be opened
819     {
820         settingsfile.close();
821         return false;
822     }
823 
824     QTextStream in(&settingsfile);
825 
826     QString SettingsLine="";             //temp variable to import the settings line by line
827     SettingsLine = in.readLine();
828 
829     // First check if the settings file is a text or data stream
830     // if data, call loadSettingsQV
831     if (SettingsLine !="***************************** WARNING *****************************")
832     {
833         settingsfile.close();
834         return loadSettingsQV();
835     }
836 
837     QString tempAppName = "asxeto";
838     QString tempFileType = "asxeto";
839     double tempAppVersion=0;
840     bool IntOk;
841 
842     // Read all lines until the [settings_global] tag or end of file if invalid
843     while ( !(SettingsLine.startsWith("[settings_global]")) && (!in.atEnd()) )
844     {
845         SettingsLine = in.readLine();
846 
847         //input the application name, version & file type --------------------------
848         if (SettingsLine.startsWith("appName="))            tempAppName = SettingsLine.remove("appName=");
849         if (SettingsLine.startsWith("appVersion="))         tempAppVersion = (SettingsLine.remove("appVersion=")).toDouble(&IntOk);
850         if (SettingsLine.startsWith("File_Type="))          tempFileType = SettingsLine.remove("File_Type=");
851     }
852 
853     //check if the file is a valid luckybackup settings file
854     if ( (tempAppName != appName) || (tempAppVersion < validSettingsVersion) || (tempFileType != "luckybackup_settings_file") )
855     {
856         settingsfile.close();
857         return false;
858     }
859 
860     // Read all lines until the [Settings_file_end] tag or end of file if invalid
861     while ( !(SettingsLine.startsWith("[Settings_file_end]")) && (!in.atEnd()) )
862     {
863         SettingsLine = in.readLine();
864 
865         if (SettingsLine.startsWith("Main_window_width="))          mainWindowWidth = (SettingsLine.remove("Main_window_width=")).toInt(&IntOk,10);
866         if (SettingsLine.startsWith("Main_window_height="))         mainWindowHeight = (SettingsLine.remove("Main_window_height=")).toInt(&IntOk,10);
867         if (SettingsLine.startsWith("Are_toolbars_locked="))        AreToolbarsLocked = (SettingsLine.remove("Are_toolbars_locked=")).toInt(&IntOk,10);
868         if (SettingsLine.startsWith("Is_combo_toolbar_visible="))   IsVisibleProfileComboToolbar = (SettingsLine.remove("Is_combo_toolbar_visible=")).toInt(&IntOk,10);
869         if (SettingsLine.startsWith("Is_profile_toolbar_visible=")) IsVisibleProfileToolbar = (SettingsLine.remove("Is_profile_toolbar_visible=")).toInt(&IntOk,10);
870         if (SettingsLine.startsWith("Is_toolbarText_visible="))     IsVisibleToolbarText = (SettingsLine.remove("Is_toolbarText_visible=")).toInt(&IntOk,10);
871         if (SettingsLine.startsWith("Default_Profile="))            defaultProfile = SettingsLine.remove("Default_Profile=");
872         if (SettingsLine.startsWith("Default_Language="))           defaultLanguage = SettingsLine.remove("Default_Language=");
873         if (SettingsLine.startsWith("Visible_info_window="))        IsVisibleInfoWindow = (SettingsLine.remove("Visible_info_window=")).toInt(&IntOk,10);
874         if (SettingsLine.startsWith("Quite_mode_output="))          showOnlyErrors = (SettingsLine.remove("Quite_mode_output=")).toInt(&IntOk,10);
875 
876         if (SettingsLine.startsWith("win_rsync_path="))             rsyncCommandPath = SettingsLine.remove("win_rsync_path=");
877         if (SettingsLine.startsWith("win_ssh_path="))               sshCommandPath = SettingsLine.remove("win_ssh_path=");
878         if (SettingsLine.startsWith("cygpath_path="))               cygpathCommand = SettingsLine.remove("cygpath_path=");
879         if (SettingsLine.startsWith("dosdev_path="))                dosdevCommand = SettingsLine.remove("dosdev_path=");
880         if (SettingsLine.startsWith("vshadowdir_path="))            vshadowDir = SettingsLine.remove("vshadowdir_path=");
881         if (SettingsLine.startsWith("tempdir_path=") && !isTempDirPath) tempDirPath = SettingsLine.remove("tempdir_path=");
882     }
883 
884     settingsfile.close();
885     ui.checkBox_onlyShowErrors -> setChecked(showOnlyErrors);
886     return true;
887 }
888 
889 //loadSettingsQV ===================================================================================================================================
890 //loads various luckybackup settings such as the default profile - data mode
loadSettingsQV()891 bool luckyBackupWindow::loadSettingsQV()
892 {
893     QFile settingsfile(settingsFile);
894     if (!settingsfile.open(QIODevice::ReadOnly))        //if the settings file cannot be opened
895     {
896         settingsfile.close();
897         return false;
898     }
899 
900     QDataStream in(&settingsfile);
901     in.setVersion(QDataStream::Qt_4_3);
902 
903     QVariant v;                     //we will import everything as QVariant using this temp variable
904     QString vString;                //temp variable to import "labels" of real data
905     QString tempAppName = "asxeto";
906     QString tempFileType = "asxeto";
907     double tempAppVersion=0;
908     in>>v;
909     if (v.toString()=="appName")
910         in >> v;
911     tempAppName = v.toString();	//input the application name & version
912     in>>v;
913     if (v.toString()=="appVersion")
914         in >> v;
915     tempAppVersion = v.toDouble();
916     in>>v;
917     if (v.toString()=="File_Type")
918         in >> v;
919     tempFileType = v.toString();	//input the file type
920 
921     //check if the file is a valid luckybackup settings file
922     if ( (tempAppName != appName) || (tempAppVersion < validSettingsVersion) || (tempFileType != "luckybackup_settings_file") )
923     {
924         settingsfile.close();
925         return false;
926     }
927 
928     in>>v;	vString = v.toString();	in >> v;	//input a label in vString and real data in v
929     while ( (vString != "Settings_file_end") && (!in.atEnd()) )
930     {
931         if (vString == "Main_window_width")         mainWindowWidth = v.toInt();
932         if (vString == "Main_window_height")        mainWindowHeight = v.toInt();
933         if (vString == "Are_toolbars_locked")       AreToolbarsLocked = v.toBool();
934         if (vString == "Is_combo_toolbar_visible")  IsVisibleProfileComboToolbar = v.toBool();
935         if (vString == "Is_profile_toolbar_visible")IsVisibleProfileToolbar = v.toBool();
936         if (vString == "Is_toolbarText_visible")    IsVisibleToolbarText = v.toBool();
937         if (vString == "Default_Profile")           defaultProfile = v.toString();
938         if (vString == "Default_Language")          defaultLanguage = v.toString();
939         if (vString == "Visible_info_window")       IsVisibleInfoWindow = v.toBool();
940 
941         if (vString == "win_rsync_path")            rsyncCommandPath = v.toString();
942         if (vString == "win_ssh_path")              sshCommandPath = v.toString();
943 
944         in>>v;	vString = v.toString();
945         if (vString!="Settings_file_end")
946                 in >> v;
947     }
948     settingsfile.close();
949 
950     saveSettings();     //save the settings file to text format
951 
952     return true;
953 }
954 
955 //arrangeLogSnap ===================================================================================================================================
956 //Rename-delete-copy logs & snaps when the current profile/task is renamed, deleted,duplicated
957 // if a task is deleted, this function is called from saveCurrentProfile()
958 // Returns true if everything went ok
arrangeLogSnap(bool PorT,QString ActionTaken,QString NameToUse)959 bool luckyBackupWindow::arrangeLogSnap(bool PorT,QString ActionTaken,QString NameToUse)
960 {
961     // PorT is "1" for profile and "0" for task
962     // ActionTaken can become "rename", "delete" ,"duplicate"
963     // NameToUse is the new name of the current profile if rename/duplicate or the file to be deleted or the old name of the task that was renamed/deleted
964 
965     bool whatToReturn1 = false, whatToReturn2 = false;
966     QStringList filtersSnapLog, snapListFiles, logsListFiles;
967     if (PorT)       // we're talking about a profile
968         filtersSnapLog << profileName + "-*";       // profileName is the old profile name
969     else            // we're talking about a task
970         filtersSnapLog << profileName + "-" + NameToUse + "-*"; // NameToUse is the name of the task that was deleted/renamed (before it was renamed)
971 
972     // QSTringLists with all files to be manipulated
973     QDir snapTempDir(snapChangesDir), logTempDir(logDir);
974     snapListFiles = snapTempDir.entryList(filtersSnapLog,QDir::AllEntries | QDir::Hidden | QDir::NoDotAndDotDot,QDir::Name);
975     logsListFiles = logTempDir.entryList(filtersSnapLog,QDir::AllEntries | QDir::Hidden | QDir::NoDotAndDotDot,QDir::Name);
976 
977     // actions for snap .changes files
978     for (int count = 0; count < snapListFiles.size(); ++count)
979     {
980         snapfile.setFileName(snapChangesDir + snapListFiles.at(count));     // QFile
981         snapchangesfilename = snapfile.fileName();                          // QString - old filename
982 
983         // the new snap .changes filename (QString) - replace either profilename or task name
984         if (PorT)
985             snapchangesfilename.replace(SLASH + profileName + "-" ,
986                                         SLASH + NameToUse   + "-" ,Qt::CaseSensitive);  // QString - new filename (profile)
987         else
988             snapchangesfilename.replace(SLASH + profileName + "-" + NameToUse + "-",
989                                         SLASH + profileName + "-" + Operation[currentOperation] -> GetName() + "-",Qt::CaseSensitive);  // QString - new filename (task)
990 
991         // and take some action
992         if (ActionTaken == "delete")
993             whatToReturn1 = snapfile.remove();
994         if (ActionTaken == "rename")
995             whatToReturn1 = snapfile.rename(snapchangesfilename);
996         if (ActionTaken == "duplicate")     //only for profile. If a task is duplicated logs & snaps are reset
997             whatToReturn1 = snapfile.copy(snapchangesfilename);
998     }
999 
1000     // actions for snap log files
1001     for (int count = 0; count < logsListFiles.size(); ++count)
1002     {
1003         logfile.setFileName(logDir + logsListFiles.at(count));     // QFile
1004         logfilename = logfile.fileName();                          // QString - old filename
1005 
1006         // the new log filename (QString) - replace either profilename or task name
1007         if (PorT)
1008             logfilename.replace(SLASH + profileName + "-",
1009                                 SLASH + NameToUse   + "-",Qt::CaseSensitive);  // QString - new filename (profile)
1010         else
1011             logfilename.replace("-" + NameToUse +"-",
1012                                 "-" + Operation[currentOperation] -> GetName() +"-",Qt::CaseSensitive);  // QString - new filename (task)
1013 
1014         // and take some action
1015         if (ActionTaken == "delete")
1016             whatToReturn2 = logfile.remove();
1017         if (ActionTaken == "rename")
1018             whatToReturn2 = logfile.rename(logfilename);
1019         if (ActionTaken == "duplicate")     //only for profile. If a task is duplicated logs & snaps are reset
1020             whatToReturn2 = logfile.copy(logfilename);
1021     }
1022 
1023     bool whatToReturn = whatToReturn1 && whatToReturn2; // return true if both snaps & log actions finished successfully
1024     return whatToReturn;
1025 }
1026 
1027 // end of functions.cpp ---------------------------------------------------------------------------
1028 
1029