1 | /**
|
---|
2 | * Copyright (C) 2017 - Fábio Bento (random-guy)
|
---|
3 | *
|
---|
4 | * This library is distributed under the MIT License. See notice at the end
|
---|
5 | * of this file.
|
---|
6 | *
|
---|
7 | */
|
---|
8 |
|
---|
9 | #include "util.h"
|
---|
10 |
|
---|
11 | namespace Util{
|
---|
12 |
|
---|
13 | namespace FileSystem {
|
---|
14 |
|
---|
15 | QString normalizePath(QString path){
|
---|
16 | return path.replace("\\","/");
|
---|
17 | }
|
---|
18 |
|
---|
19 | QString cutName(QString path){
|
---|
20 | return path.remove(0,path.lastIndexOf('/')).remove('"');
|
---|
21 | }
|
---|
22 |
|
---|
23 | QString cutNameWithoutBackSlash(QString path){
|
---|
24 | return cutName(path).remove('/');
|
---|
25 | }
|
---|
26 |
|
---|
27 | QString normalizeAndQuote(QString path){
|
---|
28 | return String::insertQuotes(normalizePath(path));
|
---|
29 | }
|
---|
30 |
|
---|
31 | // Created from scratch
|
---|
32 | bool copyDir(const QString &fromPath, QString toPath, const bool isRecursive){
|
---|
33 | QDir fromDir(fromPath);
|
---|
34 | QDir toDir(toPath);
|
---|
35 |
|
---|
36 | if(!toDir.mkdir(fromDir.dirName())){ // create the folder in the destination
|
---|
37 | return false;
|
---|
38 | }
|
---|
39 |
|
---|
40 | // Update toPath to include the folder from "fromPath"
|
---|
41 | toPath = toPath + "/" + fromDir.dirName();
|
---|
42 | toDir = QDir(toPath);
|
---|
43 |
|
---|
44 | for(const QFileInfo &currFileInfo : fromDir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot)){
|
---|
45 |
|
---|
46 | if(currFileInfo.isFile()){
|
---|
47 |
|
---|
48 | QFile destFile(toPath + "/" + currFileInfo.fileName());
|
---|
49 |
|
---|
50 | if(!QFile::copy(currFileInfo.absoluteFilePath(),toPath + "/" + currFileInfo.fileName())){
|
---|
51 | return false;
|
---|
52 | }
|
---|
53 | }
|
---|
54 | else if(isRecursive && currFileInfo.isDir() && currFileInfo.absoluteFilePath() != fromDir.absolutePath()){
|
---|
55 |
|
---|
56 | if(!copyDir(currFileInfo.absoluteFilePath(), toPath, isRecursive)){
|
---|
57 | return false;
|
---|
58 | }
|
---|
59 | }
|
---|
60 | }
|
---|
61 |
|
---|
62 | return true;
|
---|
63 | }
|
---|
64 |
|
---|
65 | //Copied from here: http://stackoverflow.com/questions/2536524/copy-directory-using-qt (ty roop)
|
---|
66 | bool rmDir(const QString &dirPath)
|
---|
67 | {
|
---|
68 | QDir dir(dirPath);
|
---|
69 | if (!dir.exists())
|
---|
70 | return true;
|
---|
71 | for(const QFileInfo &info : dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot)) {
|
---|
72 | if (info.isDir()) {
|
---|
73 | if (!rmDir(info.filePath()))
|
---|
74 | return false;
|
---|
75 | } else {
|
---|
76 | if (!dir.remove(info.fileName()))
|
---|
77 | return false;
|
---|
78 | }
|
---|
79 | }
|
---|
80 | QDir parentDir(QFileInfo(dirPath).path());
|
---|
81 | return parentDir.rmdir(QFileInfo(dirPath).fileName());
|
---|
82 | }
|
---|
83 |
|
---|
84 | // Gets all files from a folder filtered by a given wildcard
|
---|
85 | QStringList getFolderFilesByWildcard(const QString &entryFolder, const QString &wildcard, bool isRecursive){
|
---|
86 |
|
---|
87 | QStringList filesFound; // result files with absolute path
|
---|
88 |
|
---|
89 | QDirIterator it(entryFolder, QDir::Files, (isRecursive ? QDirIterator::Subdirectories : QDirIterator::NoIteratorFlags));
|
---|
90 |
|
---|
91 | while (it.hasNext()){
|
---|
92 | filesFound << it.next();
|
---|
93 | }
|
---|
94 |
|
---|
95 | return filterFilesByWildcard(filesFound, wildcard);
|
---|
96 | }
|
---|
97 |
|
---|
98 | // Supports wildcards, and subdirectories with wildcard e.g.:
|
---|
99 | // *.xml
|
---|
100 | // /myXmls/*.xml
|
---|
101 | //
|
---|
102 | // online helper: https://regex101.com/
|
---|
103 | QStringList filterFilesByWildcard(const QStringList &filePaths, const QString &wildcard){
|
---|
104 | QStringList resultFiles;
|
---|
105 | QString formattedWildcard;
|
---|
106 |
|
---|
107 | if(wildcard.trimmed().isEmpty()){
|
---|
108 | return resultFiles;
|
---|
109 | }
|
---|
110 |
|
---|
111 | formattedWildcard=normalizePath(wildcard); // Convert slashes to work in both mac and windows
|
---|
112 |
|
---|
113 | // escape the string so '.' or '(' chars get correctly escaped
|
---|
114 | formattedWildcard = QRegularExpression::escape(formattedWildcard);
|
---|
115 |
|
---|
116 | // replace * by the corresponding regex
|
---|
117 | formattedWildcard.replace("\\*",".*");
|
---|
118 |
|
---|
119 | // replace ? by the corresponding regex
|
---|
120 | formattedWildcard.replace("\\?",".");
|
---|
121 |
|
---|
122 | // if it doesn't start with any regex wildcard or a subdirectory slash, add a slash to beginning (so the file/folder matches at least the root folder)
|
---|
123 | // We use \\/ instead of / because it was escaped
|
---|
124 | if(!formattedWildcard.startsWith("\\/") && !formattedWildcard.startsWith(".*") && !formattedWildcard.startsWith(".")){
|
---|
125 | formattedWildcard = "\\/" + formattedWildcard;
|
---|
126 | }
|
---|
127 |
|
---|
128 | // if it is a subdirectory add * to match
|
---|
129 | if(formattedWildcard.startsWith("\\/")){
|
---|
130 | formattedWildcard = ".*" + formattedWildcard;
|
---|
131 | }
|
---|
132 |
|
---|
133 | formattedWildcard = "^" + formattedWildcard + "$"; // we want a full match (http://stackoverflow.com/a/5752852)
|
---|
134 |
|
---|
135 | QRegularExpression regex(formattedWildcard);
|
---|
136 |
|
---|
137 | for(const QString ¤tFile : filePaths){
|
---|
138 |
|
---|
139 | if(regex.match(currentFile).hasMatch()){
|
---|
140 | resultFiles << currentFile;
|
---|
141 | }
|
---|
142 |
|
---|
143 | }
|
---|
144 |
|
---|
145 | return resultFiles;
|
---|
146 | }
|
---|
147 |
|
---|
148 | // Returns empty QString on failure.
|
---|
149 | // Based from here: http://www.qtcentre.org/archive/index.php/t-35674.html (thanks wysota!)
|
---|
150 | QString fileHash(const QString &fileName, QCryptographicHash::Algorithm hashAlgorithm)
|
---|
151 | {
|
---|
152 |
|
---|
153 | QCryptographicHash crypto(hashAlgorithm);
|
---|
154 | QFile file(fileName);
|
---|
155 | file.open(QFile::ReadOnly);
|
---|
156 | while(!file.atEnd()){
|
---|
157 | crypto.addData(file.read(8192));
|
---|
158 | }
|
---|
159 | QByteArray hash = crypto.result();
|
---|
160 |
|
---|
161 | return QString(crypto.result().toHex());
|
---|
162 |
|
---|
163 | }
|
---|
164 |
|
---|
165 |
|
---|
166 | /**
|
---|
167 | Gets application directory. In mac os gets the .app directory
|
---|
168 | **/
|
---|
169 | QString getAppPath(){
|
---|
170 | #ifdef Q_OS_MAC
|
---|
171 | QDir dir = QDir(QCoreApplication::applicationDirPath());
|
---|
172 | if(dir.absolutePath().contains(".app")){ // include bundle, but we don't want it
|
---|
173 | dir.cdUp();
|
---|
174 | dir.cdUp();
|
---|
175 | dir.cdUp();
|
---|
176 | }
|
---|
177 | return dir.absolutePath();
|
---|
178 | #else
|
---|
179 | return QDir::currentPath();
|
---|
180 | #endif
|
---|
181 | }
|
---|
182 |
|
---|
183 | bool backupFile(const QString &file, QString newFilename){
|
---|
184 |
|
---|
185 | if(newFilename.isEmpty()){
|
---|
186 | newFilename = file;
|
---|
187 | }
|
---|
188 |
|
---|
189 | return QFile::copy(file, newFilename+".bak");
|
---|
190 | }
|
---|
191 |
|
---|
192 | }
|
---|
193 |
|
---|
194 | namespace String {
|
---|
195 |
|
---|
196 | QString insertApostrophes(const QString &currString){
|
---|
197 | return "'"+currString+"'";
|
---|
198 | }
|
---|
199 |
|
---|
200 | QString insertQuotes(const QString &currString){
|
---|
201 | return "\""+currString+"\"";
|
---|
202 | }
|
---|
203 |
|
---|
204 | QString fullTrim(QString str) {
|
---|
205 |
|
---|
206 | str = str.simplified(); //convert all invisible chars in normal whitespaces
|
---|
207 | str.replace( " ", "" );
|
---|
208 |
|
---|
209 | return str;
|
---|
210 | }
|
---|
211 |
|
---|
212 | QStringList substring(QString myString, QString separator, Qt::CaseSensitivity cs){
|
---|
213 | QStringList result = QStringList();
|
---|
214 | int currIdx=0, nextIdx=0;
|
---|
215 |
|
---|
216 | while(true){
|
---|
217 | nextIdx=myString.indexOf(separator,currIdx,cs);
|
---|
218 | result << myString.mid(currIdx,nextIdx-currIdx);
|
---|
219 | if(nextIdx==-1) break;
|
---|
220 | currIdx=nextIdx+1;
|
---|
221 | }
|
---|
222 |
|
---|
223 | return result;
|
---|
224 | }
|
---|
225 |
|
---|
226 | QString normalizeDecimalSeparator(QString value){
|
---|
227 | return value.replace(',','.');
|
---|
228 | }
|
---|
229 |
|
---|
230 | //Searches for the QString "toSearch" in the "myString" variable backward
|
---|
231 | //Returns the index of the first match or -1 if not found
|
---|
232 | int indexOfBackward(QString myString, QString toSearch, int from){
|
---|
233 | int myStringSize=myString.size();
|
---|
234 | int toSearchSize=toSearch.size();
|
---|
235 |
|
---|
236 | if(from==-1){
|
---|
237 | from=myStringSize;
|
---|
238 | }
|
---|
239 |
|
---|
240 | int i=from;
|
---|
241 |
|
---|
242 | while(i>=0){
|
---|
243 | for(int j=toSearchSize-1; j>=0; j--){
|
---|
244 | i--;
|
---|
245 | if(myString.at(i)!=toSearch.at(j)){
|
---|
246 | break;
|
---|
247 | }
|
---|
248 | if(j==0){
|
---|
249 | return i;
|
---|
250 | }
|
---|
251 | }
|
---|
252 | }
|
---|
253 |
|
---|
254 | return -1;
|
---|
255 | }
|
---|
256 |
|
---|
257 | // no problem here with "temporary" cstr
|
---|
258 | // https://stackoverflow.com/questions/1971183/when-does-c-allocate-deallocate-string-literals
|
---|
259 | const char* boolToCstr(bool currentBoolean){
|
---|
260 | return currentBoolean ? "true" : "false";
|
---|
261 | }
|
---|
262 |
|
---|
263 | }
|
---|
264 |
|
---|
265 | #ifdef QT_GUI_LIB
|
---|
266 | namespace Dialogs {
|
---|
267 |
|
---|
268 | void showInfo(const QString &message){
|
---|
269 | QMessageBox msgBox;
|
---|
270 | msgBox.setIcon(QMessageBox::Information);
|
---|
271 | msgBox.setText(message);
|
---|
272 | msgBox.exec();
|
---|
273 | }
|
---|
274 |
|
---|
275 | void showRichInfo(const QString &message){
|
---|
276 | QMessageBox msgBox;
|
---|
277 | msgBox.setTextFormat(Qt::RichText);
|
---|
278 | msgBox.setIcon(QMessageBox::Information);
|
---|
279 | msgBox.setText(message);
|
---|
280 | msgBox.exec();
|
---|
281 | }
|
---|
282 |
|
---|
283 | void showWarning(const QString &message){
|
---|
284 | QMessageBox msgBox;
|
---|
285 | msgBox.setIcon(QMessageBox::Warning);
|
---|
286 | msgBox.setText(message);
|
---|
287 | msgBox.exec();
|
---|
288 | }
|
---|
289 |
|
---|
290 | void showError(const QString &message){
|
---|
291 | QMessageBox msgBox;
|
---|
292 | msgBox.setIcon(QMessageBox::Critical);
|
---|
293 | msgBox.setText(message);
|
---|
294 | msgBox.exec();
|
---|
295 | }
|
---|
296 |
|
---|
297 | void showRichError(const QString &message){
|
---|
298 | QMessageBox msgBox;
|
---|
299 | msgBox.setIcon(QMessageBox::Critical);
|
---|
300 | msgBox.setText(message);
|
---|
301 | msgBox.exec();
|
---|
302 | }
|
---|
303 |
|
---|
304 | bool showQuestion(QWidget * parent, QString message, QMessageBox::StandardButton standardButton){
|
---|
305 | return QMessageBox::question (parent, "Are you sure?", message, QMessageBox::Yes | QMessageBox::No, standardButton)==QMessageBox::Yes;
|
---|
306 | }
|
---|
307 |
|
---|
308 | QMessageBox::StandardButton showQuestionWithCancel(QWidget * parent, QString message, QMessageBox::StandardButton standardButton){
|
---|
309 | return QMessageBox::question (parent, "Are you sure?", message, QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, standardButton);
|
---|
310 | }
|
---|
311 |
|
---|
312 | QStringList multipleDirSelection(const QString &title){
|
---|
313 | QFileDialog w;
|
---|
314 |
|
---|
315 | // We need to use non native dialog, because native doesn't support multiple folder selection
|
---|
316 | w.setOption(QFileDialog::DontUseNativeDialog,true);
|
---|
317 |
|
---|
318 | w.setFileMode(QFileDialog::DirectoryOnly);
|
---|
319 |
|
---|
320 | w.setWindowTitle(title);
|
---|
321 |
|
---|
322 | QTreeView *t = w.findChild<QTreeView*>();
|
---|
323 |
|
---|
324 | if (t) {
|
---|
325 | t->setSelectionMode(QAbstractItemView::MultiSelection);
|
---|
326 | }
|
---|
327 |
|
---|
328 | if(w.exec()){ //if accepted
|
---|
329 | return w.selectedFiles();
|
---|
330 | }
|
---|
331 | return QStringList(); //return empty
|
---|
332 | }
|
---|
333 |
|
---|
334 | }
|
---|
335 | #endif
|
---|
336 |
|
---|
337 | namespace Validation {
|
---|
338 |
|
---|
339 | // Check if any string in the list is empty
|
---|
340 | bool checkEmptySpaces(QStringList toCheck){
|
---|
341 | for (const QString ¤t : toCheck){
|
---|
342 | if(current.trimmed().isEmpty()){
|
---|
343 | return true; //There are empty spaces
|
---|
344 | }
|
---|
345 | }
|
---|
346 | return false;
|
---|
347 | }
|
---|
348 |
|
---|
349 | bool checkIfIntegers(QStringList toCheck){
|
---|
350 | for (const QString ¤t : toCheck){
|
---|
351 | if(!isStringInteger(current)){
|
---|
352 | return true; // Some aren't valid integers
|
---|
353 | }
|
---|
354 | }
|
---|
355 | return false;
|
---|
356 | }
|
---|
357 |
|
---|
358 | bool checkIfDoubles(QStringList toCheck){
|
---|
359 | for (const QString ¤t : toCheck){
|
---|
360 | if(!isStringDouble(current)){
|
---|
361 | return true; // Some aren't valid doubles
|
---|
362 | }
|
---|
363 | }
|
---|
364 | return false;
|
---|
365 | }
|
---|
366 |
|
---|
367 | bool isStringInteger(QString myString){
|
---|
368 | bool isNumber;
|
---|
369 |
|
---|
370 | myString.toInt(&isNumber); //convert to int and see if it succeeds
|
---|
371 |
|
---|
372 | return isNumber;
|
---|
373 | }
|
---|
374 |
|
---|
375 | bool isStringDouble(QString myString){
|
---|
376 | bool isDouble;
|
---|
377 |
|
---|
378 | myString.toDouble(&isDouble); //convert to double and see if it succeeds
|
---|
379 |
|
---|
380 | return isDouble;
|
---|
381 | }
|
---|
382 |
|
---|
383 | }
|
---|
384 |
|
---|
385 | namespace System {
|
---|
386 |
|
---|
387 | #ifdef QT_GUI_LIB
|
---|
388 | // From here: http://stackoverflow.com/questions/17893328/qt-getting-the-screen-resolution-without-the-extended-monitor ty Chris
|
---|
389 | QRect getScreenResolution(){
|
---|
390 | QDesktopWidget widget;
|
---|
391 | return widget.availableGeometry(widget.primaryScreen()); // or screenGeometry(), depending on your needs
|
---|
392 | }
|
---|
393 | #endif
|
---|
394 |
|
---|
395 | }
|
---|
396 |
|
---|
397 | #ifdef QT_GUI_LIB
|
---|
398 | namespace TableWidget {
|
---|
399 |
|
---|
400 |
|
---|
401 | void addRow(QTableWidget *myTable, QStringList &columns){
|
---|
402 | //Get actual number rows
|
---|
403 | int twSize=myTable->rowCount();
|
---|
404 |
|
---|
405 | //increase the rows for the new item
|
---|
406 | myTable->setRowCount(twSize+1);
|
---|
407 |
|
---|
408 | //Add to table and list to
|
---|
409 | for(int i=0; i<columns.size(); i++){
|
---|
410 | QTableWidgetItem *newColumn = new QTableWidgetItem(columns[i]);
|
---|
411 | myTable->setItem(twSize,i,newColumn);
|
---|
412 | // Add a tooltip with with the cell content
|
---|
413 | myTable->item(twSize,i)->setToolTip(myTable->item(twSize,i)->text());
|
---|
414 | }
|
---|
415 |
|
---|
416 | }
|
---|
417 |
|
---|
418 |
|
---|
419 | QModelIndexList getSelectedRows(QTableWidget *myTable){
|
---|
420 | return myTable->selectionModel()->selectedRows();
|
---|
421 | }
|
---|
422 |
|
---|
423 | QModelIndexList getCurrentRows(QTableWidget *myTable){
|
---|
424 |
|
---|
425 | QModelIndexList oldSelection = getSelectedRows(myTable);
|
---|
426 |
|
---|
427 | myTable->selectAll();
|
---|
428 |
|
---|
429 | QModelIndexList allRows = getSelectedRows(myTable);
|
---|
430 |
|
---|
431 | myTable->selectionModel()->clearSelection();
|
---|
432 |
|
---|
433 | // Restore old selection
|
---|
434 | for(const QModelIndex ¤tIndex : oldSelection){
|
---|
435 | myTable->selectionModel()->select(currentIndex, QItemSelectionModel::Select | QItemSelectionModel::SelectionFlag::Rows);
|
---|
436 | }
|
---|
437 |
|
---|
438 | return allRows;
|
---|
439 | }
|
---|
440 |
|
---|
441 | int getNumberSelectedRows(QTableWidget *myTable){
|
---|
442 | return getSelectedRows(myTable).size();
|
---|
443 | }
|
---|
444 |
|
---|
445 | void clearContents(QTableWidget *myTable, const QString ¬hingToClearMessage, const QString &questionToClear){
|
---|
446 |
|
---|
447 | if(myTable->rowCount()==0){
|
---|
448 | Dialogs::showInfo(nothingToClearMessage);
|
---|
449 | return;
|
---|
450 | }
|
---|
451 |
|
---|
452 | if(Dialogs::showQuestion(myTable, questionToClear)){
|
---|
453 | clearContentsNoPrompt(myTable);
|
---|
454 | }
|
---|
455 |
|
---|
456 | }
|
---|
457 |
|
---|
458 | void clearContentsNoPrompt(QTableWidget *myTable){
|
---|
459 | myTable->clearContents();
|
---|
460 | myTable->setRowCount(0);
|
---|
461 | }
|
---|
462 |
|
---|
463 | // Adapted from here:
|
---|
464 | // http://stackoverflow.com/questions/29176317/qtablewidget-checkbox-get-state-and-location
|
---|
465 | void addCheckBox(QTableWidget *myTable, int row, int column, QCheckBox *checkbox){
|
---|
466 | if(checkbox == nullptr){
|
---|
467 | checkbox = new QCheckBox();
|
---|
468 | }
|
---|
469 |
|
---|
470 | QWidget *auxLayoutWidget = new QWidget(myTable);
|
---|
471 |
|
---|
472 | QHBoxLayout* checkBoxLayout = new QHBoxLayout();
|
---|
473 | checkBoxLayout->setContentsMargins(0,0,0,0);
|
---|
474 | checkBoxLayout->addWidget(checkbox);
|
---|
475 | checkBoxLayout->setAlignment(Qt::AlignCenter);
|
---|
476 | checkBoxLayout->setSpacing(0);
|
---|
477 | auxLayoutWidget->setLayout(checkBoxLayout);
|
---|
478 |
|
---|
479 | myTable->setCellWidget(row, column, auxLayoutWidget);
|
---|
480 | }
|
---|
481 |
|
---|
482 | // Adapted from here:
|
---|
483 | // http://stackoverflow.com/questions/29176317/qtablewidget-checkbox-get-state-and-location
|
---|
484 | QCheckBox* getCheckBoxFromCell(QTableWidget *myTable, int row, int column){
|
---|
485 | return dynamic_cast<QCheckBox*>(myTable->cellWidget(row, column)->findChild<QCheckBox *>());
|
---|
486 | }
|
---|
487 |
|
---|
488 | // Adapted from here:
|
---|
489 | // http://www.qtcentre.org/threads/3386-QTableWidget-move-row
|
---|
490 | // Thanks jpn
|
---|
491 | void swapRows(QTableWidget *myTable, const int indexSourceRow, const int indexDestinationRow, bool selectSwappedRow)
|
---|
492 | {
|
---|
493 | // takes and returns the whole row
|
---|
494 | auto takeRow = [&myTable](int row) -> QList<QTableWidgetItem*>
|
---|
495 | {
|
---|
496 | QList<QTableWidgetItem*> rowItems;
|
---|
497 | for (int col = 0; col < myTable->columnCount(); ++col)
|
---|
498 | {
|
---|
499 | rowItems << myTable->takeItem(row, col);
|
---|
500 | }
|
---|
501 | return rowItems;
|
---|
502 | };
|
---|
503 |
|
---|
504 | // sets the whole row
|
---|
505 | auto setRow = [&myTable](int row, const QList<QTableWidgetItem*>& rowItems)
|
---|
506 | {
|
---|
507 | for (int col = 0; col < myTable->columnCount(); ++col)
|
---|
508 | {
|
---|
509 | myTable->setItem(row, col, rowItems.at(col));
|
---|
510 | }
|
---|
511 | };
|
---|
512 |
|
---|
513 | // take whole rows
|
---|
514 | QList<QTableWidgetItem*> sourceItems = takeRow(indexSourceRow);
|
---|
515 | QList<QTableWidgetItem*> destItems = takeRow(indexDestinationRow);
|
---|
516 |
|
---|
517 | // set back in reverse order
|
---|
518 | setRow(indexSourceRow, destItems);
|
---|
519 | setRow(indexDestinationRow, sourceItems);
|
---|
520 |
|
---|
521 | if(selectSwappedRow){
|
---|
522 | myTable->selectRow(indexDestinationRow);
|
---|
523 | }
|
---|
524 | }
|
---|
525 |
|
---|
526 | void deleteSelectedRows(QTableWidget *myTable){
|
---|
527 | int size = myTable->selectionModel()->selectedRows().size();
|
---|
528 |
|
---|
529 | for(int i=0; i<size; i++){
|
---|
530 | myTable->removeRow(myTable->selectionModel()->selectedRows().at(size-i-1).row());
|
---|
531 | }
|
---|
532 | }
|
---|
533 |
|
---|
534 | }
|
---|
535 | #endif
|
---|
536 |
|
---|
537 | #ifdef QT_GUI_LIB
|
---|
538 | namespace StatusBar {
|
---|
539 |
|
---|
540 | void showError(QStatusBar * const statusBar, const QString &message){
|
---|
541 |
|
---|
542 | QPalette myPalete = QPalette();
|
---|
543 | myPalete.setColor( QPalette::WindowText, QColor(255,0,0));
|
---|
544 | statusBar->setPalette( myPalete );
|
---|
545 | statusBar->showMessage(message,10000); //display by 10 seconds
|
---|
546 |
|
---|
547 | }
|
---|
548 |
|
---|
549 | void showSuccess(QStatusBar * const statusBar,const QString &message){
|
---|
550 |
|
---|
551 | QPalette myPalete = QPalette();
|
---|
552 | myPalete.setColor( QPalette::WindowText, QColor(0,150,0));
|
---|
553 | statusBar->setPalette( myPalete );
|
---|
554 | statusBar->showMessage(message,10000); //display by 10 seconds
|
---|
555 |
|
---|
556 | }
|
---|
557 |
|
---|
558 | }
|
---|
559 | #endif
|
---|
560 |
|
---|
561 | }
|
---|
562 |
|
---|
563 |
|
---|
564 | /**
|
---|
565 | * Copyright (c) 2017 - Fábio Bento (random-guy)
|
---|
566 | *
|
---|
567 | * Permission is hereby granted, free of charge, to any person
|
---|
568 | * obtaining a copy of this software and associated documentation
|
---|
569 | * files (the "Software"), to deal in the Software without
|
---|
570 | * restriction, including without limitation the rights to use,
|
---|
571 | * copy, modify, merge, publish, distribute, sublicense, and/or sell
|
---|
572 | * copies of the Software, and to permit persons to whom the
|
---|
573 | * Software is furnished to do so, subject to the following
|
---|
574 | * conditions:
|
---|
575 | *
|
---|
576 | * The above copyright notice and this permission notice shall be
|
---|
577 | * included in all copies or substantial portions of the Software.
|
---|
578 | *
|
---|
579 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
---|
580 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
---|
581 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
---|
582 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
---|
583 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
---|
584 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
---|
585 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
---|
586 | * OTHER DEALINGS IN THE SOFTWARE.
|
---|
587 | */
|
---|