mirror of
https://gitlab.com/pholy/OSCAR-code.git
synced 2025-04-04 02:00:43 +00:00
976 lines
36 KiB
C++
976 lines
36 KiB
C++
/* user graph settings Implementation
|
||
*
|
||
* Copyright (c) 2022-2024 The OSCAR Team
|
||
*
|
||
* This file is subject to the terms and conditions of the GNU General Public
|
||
* License. See the file COPYING in the main directory of the source code
|
||
* for more details. */
|
||
|
||
#define TEST_MACROS_ENABLEDoff
|
||
#include <test_macros.h>
|
||
|
||
#include <QMessageBox>
|
||
#include <QAbstractButton>
|
||
#include <QWindow>
|
||
#include <QApplication>
|
||
#include <QScrollArea>
|
||
#include <QVBoxLayout>
|
||
#include <QTextEdit>
|
||
#include <QPixmap>
|
||
#include <QSize>
|
||
#include <QChar>
|
||
#include "SleepLib/profiles.h"
|
||
#include "saveGraphLayoutSettings.h"
|
||
|
||
|
||
|
||
#define USE_FRAMELESS_WINDOW_off
|
||
#define USE_PROFILE_SPECIFIC_FOLDERoff // off implies saved layouts worked for all profiles.
|
||
|
||
SaveGraphLayoutSettings::SaveGraphLayoutSettings(QString title,QWidget* parent) : parent(parent),title(title)
|
||
{
|
||
createSaveFolder();
|
||
if (dir==nullptr) return;
|
||
dir->setFilter(QDir::Files | QDir::Readable | QDir::Writable | QDir::NoSymLinks);
|
||
|
||
QString descFileName = dirName+title.toLower()+".descriptions.txt";
|
||
descriptionMap = new DescriptionMap (dir,descFileName);
|
||
|
||
createMenu() ;
|
||
|
||
menu.dialog->connect(menuAddFullBtn, SIGNAL(clicked()), this, SLOT (addFull_feature() ));
|
||
menu.dialog->connect(menuAddBtn, SIGNAL(clicked()), this, SLOT (add_feature() ));
|
||
menu.dialog->connect(menuRestoreBtn, SIGNAL(clicked()), this, SLOT (restore_feature() ));
|
||
menu.dialog->connect(menuUpdateBtn, SIGNAL(clicked()), this, SLOT (update_feature() ));
|
||
menu.dialog->connect(menuRenameBtn, SIGNAL(clicked()), this, SLOT (rename_feature() ));
|
||
menu.dialog->connect(menuDeleteBtn, SIGNAL(clicked()), this, SLOT (delete_feature() ));
|
||
menu.dialog->connect(menuHelpBtn, SIGNAL(clicked()), this, SLOT (help_feature() ));
|
||
menu.dialog->connect(menuList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*) ));
|
||
menu.dialog->connect(menuList, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged() ));
|
||
|
||
|
||
|
||
singleLineRe = new QRegularExpression( QString("^\\s*([^\\r\\n]{0,%1})").arg(1+maxDescriptionLen) );
|
||
fileNumRe = new QRegularExpression( QString("%1(\\d+)(.shg)?$").arg(fileBaseName) );
|
||
parseFilenameRe = new QRegularExpression(QString("^(%1[.](%2(\\d*)))[.]shg$").arg(title).arg(fileBaseName));
|
||
}
|
||
|
||
SaveGraphLayoutSettings::~SaveGraphLayoutSettings()
|
||
{
|
||
|
||
if (dir==nullptr) {return;}
|
||
menu.dialog->disconnect(menuAddFullBtn, SIGNAL(clicked()), this, SLOT (addFull_feature() ));
|
||
menu.dialog->disconnect(menuAddBtn, SIGNAL(clicked()), this, SLOT (add_feature() ));
|
||
menu.dialog->disconnect(menuRestoreBtn, SIGNAL(clicked()), this, SLOT (restore_feature() ));
|
||
menu.dialog->disconnect(menuUpdateBtn, SIGNAL(clicked()), this, SLOT (update_feature() ));
|
||
menu.dialog->disconnect(menuRenameBtn, SIGNAL(clicked()), this, SLOT (rename_feature() ));
|
||
menu.dialog->disconnect(menuDeleteBtn, SIGNAL(clicked()), this, SLOT (delete_feature() ));
|
||
menu.dialog->disconnect(menuHelpBtn, SIGNAL(clicked()), this, SLOT (help_feature() ));
|
||
menu.dialog->disconnect(menuList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*) ));
|
||
menu.dialog->disconnect(menuList, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged() ));
|
||
helpDestructor();
|
||
|
||
|
||
delete descriptionMap;
|
||
delete singleLineRe;
|
||
delete fileNumRe;
|
||
delete parseFilenameRe;
|
||
}
|
||
|
||
void SaveGraphLayoutSettings::createSaveFolder() {
|
||
// Insure that the save folder exists
|
||
// Get the directory name for the save files
|
||
//QString layoutFileFolder = "savedGraphLayoutSettings/";
|
||
QString layoutFileFolder = "layoutSettings/";
|
||
|
||
#if 0
|
||
// home directory for the current profile.
|
||
QString baseName = p_profile->Get("{DataFolder}/");
|
||
|
||
#else
|
||
// home directory for all profiles.
|
||
// allows settings to be shared accross profiles.
|
||
QString baseName = p_pref->Get("{home}/");
|
||
|
||
#endif
|
||
|
||
dirName = baseName+layoutFileFolder;
|
||
|
||
// Check if the save folder exists
|
||
QDir* tmpDir = new QDir(dirName);
|
||
if (!tmpDir->exists()) {
|
||
QDir* baseDir=new QDir(baseName);
|
||
if (!baseDir->exists()) {
|
||
// Base folder does not exist - terminate
|
||
return ;
|
||
}
|
||
// saved Setting folder does not exist. make it
|
||
if (!baseDir->mkdir(dirName)) {
|
||
// Did not create the folder.
|
||
return ;
|
||
}
|
||
tmpDir = new QDir(dirName);
|
||
// double check if save folder exists or not.
|
||
if (!tmpDir->exists()) {
|
||
return ;
|
||
}
|
||
}
|
||
dir=tmpDir;
|
||
}
|
||
|
||
QPushButton* SaveGraphLayoutSettings::menuBtn(QString name, QIcon* icon, QString style,QSizePolicy::Policy hPolicy,QString tooltip) {
|
||
return newBtnRtn(menuLayoutButtons, name, icon, style, hPolicy,tooltip) ;
|
||
}
|
||
|
||
//QPushButton* SaveGraphLayoutSettings::helpBtn(QString name, QIcon* icon, QString style,QSizePolicy::Policy hPolicy,QString tooltip) {
|
||
//return newBtnRtn(menuLayoutButtons, name, icon, style, hPolicy,tooltip) ;
|
||
//}
|
||
|
||
QPushButton* SaveGraphLayoutSettings::newBtnRtn(QHBoxLayout* layout,QString name, QIcon* icon, QString style,QSizePolicy::Policy hPolicy,QString tooltip) {
|
||
QPushButton* button = new QPushButton(name, menu.dialog);
|
||
button->setIcon(*icon);
|
||
button->setStyleSheet(style);
|
||
button->setSizePolicy(hPolicy,QSizePolicy::Fixed);
|
||
button->setToolTip(tooltip);
|
||
button->setToolTipDuration(AppSetting->tooltipTimeout());
|
||
button->setFont(*mediumfont);
|
||
layout->addWidget(button);
|
||
return button;
|
||
}
|
||
|
||
void SaveGraphLayoutSettings::createStyleSheets() {
|
||
styleOn= calculateButtonStyle(true,false);
|
||
styleOff= calculateButtonStyle(false,false);
|
||
styleExit= calculateButtonStyle(true,true);
|
||
styleMessageBox=
|
||
"QMessageBox { "
|
||
"background-color:yellow;"
|
||
//"color:black;"
|
||
"color:red;"
|
||
"border: 2px solid black;"
|
||
"text-align: right;"
|
||
"font-size: 16px;"
|
||
"}"
|
||
"QTextEdit {"
|
||
"background-color:lightblue;"
|
||
//"color:black;"
|
||
"color:red;"
|
||
"border: 9px solid black;"
|
||
"text-align: center;"
|
||
"vertical-align:top;"
|
||
"}"
|
||
;
|
||
styleDialog= QString ( R"( QDialog { border: 3px solid black; } )") ;
|
||
}
|
||
|
||
|
||
void SaveGraphLayoutSettings::createMenu() {
|
||
if(menu.dialog) return;
|
||
initDialog(menu,tr("Manage Save Layout Settings") );
|
||
|
||
createStyleSheets();
|
||
|
||
QString styleDialog( R"( QDialog { border: 3px solid black; } )") ;
|
||
menu.dialog->setStyleSheet(styleDialog);
|
||
|
||
menuLayoutButtons = new QHBoxLayout();
|
||
|
||
menuAddFullBtn = menuBtn(tr("Add" ),m_icon_add , styleOff ,QSizePolicy::Minimum, tr("Add Feature inhibited. The maximum number of Items has been exceeded.") );
|
||
menuAddBtn = menuBtn(tr("Add" ),m_icon_add , styleOn ,QSizePolicy::Minimum, tr("creates new copy of current settings."));
|
||
menuRestoreBtn = menuBtn(tr("Restore"),m_icon_restore , styleOn ,QSizePolicy::Minimum, tr("Restores saved settings from selection."));
|
||
menuRenameBtn = menuBtn(tr("Rename" ),m_icon_rename , styleOn ,QSizePolicy::Minimum, tr("Renames the selection. Must edit existing name then press enter."));
|
||
menuUpdateBtn = menuBtn(tr("Update" ),m_icon_update , styleOn ,QSizePolicy::Minimum, tr("Updates the selection with current settings."));
|
||
menuDeleteBtn = menuBtn(tr("Delete" ),m_icon_delete , styleOn ,QSizePolicy::Minimum, tr("Deletes the selection."));
|
||
menuHelpBtn = menuBtn("" ,m_icon_help , styleOn ,QSizePolicy::Fixed , tr("Expanded Help menu."));
|
||
|
||
menuList = new QListWidget(menu.dialog);
|
||
menuList->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||
menuList->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||
menuList->setFont(menu.font);
|
||
|
||
|
||
menu.layout->addLayout(menuLayoutButtons);
|
||
menu.layout->addWidget(menuList, 1);
|
||
|
||
//menuList->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred);
|
||
menuList->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum);
|
||
};
|
||
|
||
void HelpData::setDialog(QWidget* parent,QString windowsTitle) {
|
||
if (dialog) return;
|
||
open=false;
|
||
#ifdef USE_FRAMELESS_WINDOW
|
||
dialog= new QDialog(parent, Qt::FramelessWindowHint);
|
||
title.setText(QString("<h4>%1</h4>").arg(windowsTitle) );
|
||
headerLayout = new QHBoxLayout();
|
||
#else
|
||
dialog = new QDialog(nullptr, Qt::WindowTitleHint | Qt::WindowCloseButtonHint|Qt::WindowSystemMenuHint);
|
||
dialog->setWindowTitle(windowsTitle) ;
|
||
dialog->setWindowModality(Qt::WindowModal);
|
||
dialog->setStyleSheet(QString ( "QDialog { border: 3px solid black; }"));
|
||
#endif
|
||
Q_UNUSED(parent);
|
||
font = QApplication::font();
|
||
fontBold = font;
|
||
fontBold.setWeight(QFont::Bold);
|
||
layout = new QVBoxLayout(dialog);
|
||
}
|
||
|
||
void SaveGraphLayoutSettings::initDialog(
|
||
HelpData & aHelp
|
||
, QString title
|
||
) {
|
||
if(aHelp.dialog) return;
|
||
aHelp.setDialog(parent,title);
|
||
#ifdef USE_FRAMELESS_WINDOW
|
||
aHelp.headerLayout->addWidget(&aHelp.title);
|
||
aHelp.exitBtn = newBtnRtn(aHelp.headerLayout, "", m_icon_exit, styleExit , QSizePolicy::Fixed, tr("Exits the dialog menu.")) ;
|
||
aHelp.layout->addLayout(aHelp.headerLayout);
|
||
#endif
|
||
// YXXXXXXXXXXXXXXXXXXX
|
||
// dialog->setFont(font) ;
|
||
aHelp.dialog->setSizeGripEnabled(true); // allows lower right hand corner to resize dialog
|
||
aHelp.dialog->setStyleSheet(QString ( "QDialog { border: 3px solid black; }"));
|
||
}
|
||
|
||
void SaveGraphLayoutSettings::createHelp() {
|
||
createHelp(help, tr("Help Menu - Manage Layout Settings"), helpInfo());
|
||
if (help.exitBtn) help.dialog->connect(help.exitBtn, SIGNAL(clicked()), this, SLOT (help_exit_feature() ));
|
||
};
|
||
|
||
void SaveGraphLayoutSettings::createHelp(HelpData & ahelp , QString title , QString text) {
|
||
if(ahelp.dialog) return;
|
||
initDialog(ahelp,title );
|
||
|
||
ahelp.label = new QLabel(parent);
|
||
ahelp.label->setFont(ahelp.font);
|
||
ahelp.label->setText(text) ;
|
||
ahelp.layout->addWidget(ahelp.label, 1);
|
||
|
||
}
|
||
|
||
void SaveGraphLayoutSettings::helpDestructor() {
|
||
closeHelp();
|
||
closeHint();
|
||
closeMenu();
|
||
if (hint.exitBtn) hint.dialog->disconnect(hint.exitBtn, SIGNAL(clicked()), this, SLOT ( closeHint() ));
|
||
if (help.exitBtn) help.dialog->disconnect(help.exitBtn, SIGNAL(clicked()), this, SLOT ( closeHelp() ));
|
||
if (menu.exitBtn) menu.dialog->disconnect(menu.exitBtn, SIGNAL(clicked()), this, SLOT ( help_exit_feature() ));
|
||
}
|
||
|
||
#define TABLES QString(R"( <table width="100%"> )")
|
||
#define TABLEE QString(R"( </table> )")
|
||
#define CENTERS QString(R"( <div style="text-align: center;"><p> )")
|
||
#define CENTERE QString(R"( </p></div> )")
|
||
#define BREAK QString(R"( <br> )")
|
||
#define PARAS QString(R"( <p> )")
|
||
#define PARAE QString(R"( </p> )")
|
||
#define ROWS QString(R"( <tr> )")
|
||
#define ROWE QString(R"( </tr> )")
|
||
#define COLS QString(R"( <td> )")
|
||
#define COLE QString(R"( </td> )")
|
||
#define CSEP QString(R"( </th><td> )")
|
||
|
||
QString SaveGraphLayoutSettings::hintInfo() {
|
||
|
||
QStringList strList;
|
||
|
||
strList
|
||
<< CENTERS << "<b>"
|
||
<< tr("Basic Hints")
|
||
<< "</b>" << CENTERE
|
||
<< TABLES
|
||
<< ROWS << COLS << "<b>" << QString(tr("Key Sequence")) << "</b>" << CSEP << "<b>" << QString(tr("Description")) << "</b>" << COLE << ROWE
|
||
<< ROWS << COLS << QString(tr("MouseWheel")) << CSEP << QString(tr("Scrolls unpinned Graphs")) << COLE << ROWE
|
||
<< ROWS << COLS << QString(tr("Ctrl + MouseWheel")) << CSEP << QString(tr("Zooms Time Selection")) << COLE << ROWE
|
||
<< ROWS << COLS << QString(tr("LeftMouse dragDrop")) << CSEP << QString(tr("Defines Time Selection")) << COLE << ROWE
|
||
<< ROWS << COLS << QString(tr("RightMouse dragDrop")) << CSEP << QString(tr("Moves Time Selection")) << COLE << ROWE
|
||
<< ROWS << COLS << QString(tr("Ctrl + (right/left)MouseClick")) << CSEP << QString(tr("Zooms Time Selection")) << COLE << ROWE
|
||
<< ROWS << COLS << QString(tr(" (right/left)MouseClick")) << CSEP << QString(tr("Moves Time Selection")) << COLE << ROWE
|
||
<< BREAK
|
||
<< ROWS << COLS << QString(tr("(right/left) Arrow (Ctrl => faster)")) << CSEP << QString(tr("Moves Time Selection")) << COLE << ROWE
|
||
<< ROWS << COLS << QString(tr("Up/Down Arrow")) << CSEP << QString(tr("Scrolls graphs")) << COLE << ROWE
|
||
<< ROWS << COLS << QString(tr("Up/Down Arrow+Focus")) << CSEP << QString(tr("Zooms graphs")) << COLE << ROWE
|
||
<< TABLEE
|
||
<< CENTERS << "<b>"
|
||
<< tr("Graph Layout Hints")
|
||
<< "</b>" << CENTERE
|
||
<< TABLES
|
||
<< ROWS << COLS << QString(tr("Double Click Graph Title")) << CSEP << QString(tr("Toggles Pinning")) << COLE << ROWE
|
||
<< ROWS << COLS << QString(tr("Daily:Double Click Y-axis label")) << CSEP << QString(tr("Toggle Time Selection Auto Zoom")) << COLE << ROWE
|
||
<< ROWS << COLS << QString(tr("DragDrop Graph Title")) << CSEP << QString(tr("Reorders Graph layout")) << COLE << ROWE
|
||
<< ROWS << COLS << QString(tr("DragDrop graph’s bottom line")) << CSEP << QString(tr("Changes Size of Graphs")) << COLE << ROWE
|
||
<< ROWS << COLS << QString(tr("Layout Button (next to Graph Button)")) << CSEP << QString(tr("Save / Restore Graph Layouts")) << COLE << ROWE
|
||
<< TABLEE
|
||
<< CENTERS << "<b>"
|
||
<< tr("Daily Graph Hints")
|
||
<< "</b>" << CENTERE
|
||
<< TABLES
|
||
<< ROWS << COLS << QString(tr("Click on date")) << CSEP << QString(tr("Toggle Calendar on/off")) << COLE << ROWE
|
||
<< ROWS << COLS << QString(tr("Detailed: Click on colored event")) << CSEP << QString(tr("Jump to event tab with event opened")) << COLE << ROWE
|
||
<< ROWS << COLS << QString(tr("Detailed: Click on a session (at bottom)")) << CSEP << QString(tr("Toggle session disable / enable session")) << COLE << ROWE
|
||
<< ROWS << COLS << QString(tr("Event: Click on an event")) << CSEP << QString(tr("Time Selection 3 min before event 20 sec after")) << COLE << ROWE
|
||
<< ROWS << COLS << QString(tr("Bookmark")) << CSEP << QString(tr("Save current Time Selection")) << COLE << ROWE
|
||
<< ROWS << COLS << QString(tr("Search Tab")) << CSEP << QString(tr("Search data base")) << COLE << ROWE
|
||
<< TABLEE
|
||
<< CENTERS << "<b>"
|
||
<< tr("Miscellaneous Hints")
|
||
<< "</b>" << CENTERE
|
||
<< TABLES
|
||
<< ROWS << COLS << QString(tr("OverView: Shift Click on a date")) << CSEP << QString(tr("Jumps to date in the Daily Tab")) << COLE << ROWE
|
||
<< ROWS << COLS << QString(tr("Daily: Event (bottom left corner) ")) << CSEP << QString(tr("Select Events to view")) << COLE << ROWE
|
||
<< ROWS << COLS << QString(tr("Graph / Chart (bottom right corner)")) << CSEP << QString(tr("Selects graphs to view")) << COLE << ROWE
|
||
<< TABLEE
|
||
;
|
||
return strList.join("\n");
|
||
}
|
||
|
||
QString SaveGraphLayoutSettings::helpInfo() {
|
||
QStringList strList;
|
||
strList<<QString("<p style=\"color:black;\">")
|
||
<<QString(tr("This feature manages the saving and restoring of Layout Settings."))
|
||
<<QString("<br>")
|
||
<<QString(tr("Layout Settings control the layout of a graph or chart."))
|
||
<<QString("<br>")
|
||
<<QString(tr("Different Layouts Settings can be saved and later restored."))
|
||
<<QString("<br> </p> <table width=\"100%\"> <tr><td><b>")
|
||
<<QString(tr("Button"))
|
||
<<QString("</b></td> <td><b>")
|
||
<<QString(tr("Description"))
|
||
<<QString("</b></td></tr> <tr><td valign=\"top\">")
|
||
<<QString(tr("Add"))
|
||
<<QString("</td> <td>")
|
||
<<QString(tr("Creates a copy of the current Layout Settings."))
|
||
<<QString("<br>")
|
||
<<QString(tr("The default description is the current date."))
|
||
<<QString("<br>")
|
||
<<QString(tr("The description may be changed."))
|
||
<<QString("<br>")
|
||
<<QString(tr("The Add button will be greyed out when maximum number is reached."))
|
||
<<QString("<br>")
|
||
<<QString("</td></tr> <tr><td><i><u>")
|
||
<<QString(tr("Other Buttons"))
|
||
<<QString("</u> </i></td> <td>")
|
||
<<QString(tr("Greyed out when there are no selections"))
|
||
<<QString("</td></tr> <tr><td>")
|
||
<<QString(tr("Restore"))
|
||
<<QString("</td> <td>")
|
||
<<QString(tr("Loads the Layout Settings from the selection. Stays Open"))
|
||
<<QString("</td></tr> <tr><td>")
|
||
<<QString(tr("Rename"))
|
||
<<QString("</td><td>")
|
||
<<QString(tr("Modify the description of the selection. Same as a double click."))
|
||
<<QString("</td></tr> <tr><td valign=\"top\">")
|
||
<<QString(tr("Update"))
|
||
<<QString("</td><td>")
|
||
<<QString(tr("Saves the current Layout Settings to the selection."))
|
||
<<QString("<br>")
|
||
<<QString(tr("Prompts for confirmation."))
|
||
<<QString("</td></tr> <tr><td valign=\"top\">")
|
||
<<QString(tr("Delete"))
|
||
<<QString("</td> <td>")
|
||
<<QString(tr("Deletes the selecton."))
|
||
<<QString("<br>")
|
||
<<QString(tr("Prompts for confirmation."))
|
||
<<QString("</td></tr> <tr><td><i><u>")
|
||
<<QString(tr("Control"))
|
||
<<QString("</u> </i></td> <td></td></tr> <tr><td>")
|
||
<<QString(tr("Exit"))
|
||
<<QString("</td> <td>")
|
||
<<QString(tr("(Red circle with a white \"X\".) Returns to OSCAR menu."))
|
||
<<QString("</td></tr> <tr><td>")
|
||
<<QString(tr("Return"))
|
||
<<QString("</td> <td>")
|
||
<<QString(tr("Next to Exit icon. Only in Help Menu. Returns to Layout menu."))
|
||
<<QString("</td></tr> <tr><td>")
|
||
<<QString(tr("Escape Key"))
|
||
<<QString("</td> <td>")
|
||
<<QString(tr("Exit the Help or Layout menu."))
|
||
<<QString("</td></tr> </table> <p><b>")
|
||
<<QString(tr("Layout Settings"))
|
||
<<QString("</b></p> <table width=\"100%\"> <tr> <td>")
|
||
<<QString(tr("* Name"))
|
||
<<QString("</td> <td>")
|
||
<<QString(tr("* Pinning"))
|
||
<<QString("</td> <td>")
|
||
<<QString(tr("* Plots Enabled"))
|
||
<<QString("</td> <td>")
|
||
<<QString(tr("* Height"))
|
||
<<QString("</td> </tr> <tr> <td>")
|
||
<<QString(tr("* Order"))
|
||
<<QString("</td> <td>")
|
||
<<QString(tr("* Event Flags"))
|
||
<<QString("</td> <td>")
|
||
<<QString(tr("* Dotted Lines"))
|
||
<<QString("</td> <td>")
|
||
<<QString(tr("* Height Options"))
|
||
<<QString("</td> </tr> </table> <p><b>")
|
||
<<QString(tr("General Information"))
|
||
<<QString("</b></p> <ul style=margin-left=\"20\"; > <li>")
|
||
<<QString(tr("Maximum description size = 80 characters. "))
|
||
<<QString("</li> <li>")
|
||
<<QString(tr("Maximum Saved Layout Settings = 30. "))
|
||
<<QString("</li> <li>")
|
||
<<QString(tr("Saved Layout Settings can be accessed by all profiles."))
|
||
<<QString("<li>")
|
||
<<QString(tr("Layout Settings only control the layout of a graph or chart."))
|
||
<<QString("<br>")
|
||
<<QString(tr("They do not contain any other data."))
|
||
<<QString("<br>")
|
||
<<QString(tr("They do not control if a graph is displayed or not."))
|
||
<<QString("</li> <li>")
|
||
<<QString(tr("Layout Settings for daily and overview are managed independantly."))
|
||
<<QString("</li> </ul>");
|
||
return strList.join("\n");
|
||
};
|
||
|
||
const QString SaveGraphLayoutSettings::calculateStyleMessageBox(QFont* font , QString& s1, QString& s2) {
|
||
QFontMetrics fm = QFontMetrics(*font);
|
||
int width = fm.boundingRect(s1).size().width();
|
||
int width2 = fm.boundingRect(s2).size().width();
|
||
width = qMax(width,width2) + iconWidthMessageBox;
|
||
|
||
QString style = QString("%1 QLabel{%2 min-width: %3px;}" ).
|
||
arg(styleMessageBox).
|
||
arg("text-align: center;" "color:black;").
|
||
arg(width);
|
||
|
||
return style;
|
||
}
|
||
|
||
bool SaveGraphLayoutSettings::verifyItem(QListWidgetItem* item,QString text,QIcon* icon) {
|
||
//if (verifyhelp() ) return false;
|
||
if (item) return true;
|
||
initminMenuListSize();
|
||
confirmAction( text ,"" , icon);
|
||
return false;
|
||
}
|
||
|
||
#if 1
|
||
bool SaveGraphLayoutSettings::confirmAction(QString top ,QString bottom,QIcon* icon,QMessageBox::StandardButtons flags , QMessageBox::StandardButton adefault, QMessageBox::StandardButton success) {
|
||
//QString topText=QString("<Center>%1</Center>").arg(top);
|
||
//QString bottomText=QString("<Center>%1</Center>").arg(bottom);
|
||
QString topText=QString("<p style=""text-align:center"">%1</p>").arg(top);
|
||
QString bottomText=QString("<p style=""text-align:center"">%1</p>").arg(bottom);
|
||
|
||
QMessageBox msgBox(menu.dialog);
|
||
msgBox.setText(topText);
|
||
msgBox.setInformativeText(bottomText);
|
||
if (icon!=nullptr) {
|
||
msgBox.setIconPixmap(icon->pixmap(QSize(iconWidthMessageBox,iconWidthMessageBox)));
|
||
}
|
||
// may be good for help menu. a pull down box with box of data. msgBox.setDetailedText("some detailed string");
|
||
msgBox.setStandardButtons(flags);
|
||
msgBox.setDefaultButton(adefault);
|
||
msgBox.setWindowFlag(Qt::FramelessWindowHint,true);
|
||
|
||
msgBox.setStyleSheet(calculateStyleMessageBox(&menu.font,top,bottom));
|
||
|
||
// displaywidgets((QWidget*)&msgBox);
|
||
bool ret= msgBox.exec()==success;
|
||
return ret;
|
||
}
|
||
#else
|
||
bool SaveGraphLayoutSettings::confirmAction(QString name ,QString question,QIcon* icon,QMessageBox::StandardButtons flags , QMessageBox::StandardButton adefault, QMessageBox::StandardButton success) {
|
||
//bool SaveGraphLayoutSettings::confirmAction(QString name,QString question,QIcon* icon)
|
||
Q_UNUSED(flags);
|
||
Q_UNUSED(adefault);
|
||
Q_UNUSED(success);
|
||
QMessageBox msgBox(menu.dialog);
|
||
msgBox.setText(question);
|
||
if (icon!=nullptr) {
|
||
msgBox.setIconPixmap(icon->pixmap(QSize(50,50)));
|
||
}
|
||
|
||
msgBox.setStandardButtons(QMessageBox::Cancel | QMessageBox::Yes );
|
||
msgBox.setDefaultButton(QMessageBox::Cancel);
|
||
msgBox.setStyleSheet(styleMessageBox);
|
||
msgBox.setWindowFlag(Qt::FramelessWindowHint,true);
|
||
|
||
return (msgBox.exec()==QMessageBox::Yes);
|
||
Q_UNUSED(name);
|
||
|
||
}
|
||
#endif
|
||
|
||
QString SaveGraphLayoutSettings::calculateButtonStyle(bool on,bool exitBtn){
|
||
QString btnStyle=QString("QPushButton{%1%2}").arg(on
|
||
?"color: black;background-color:white;"
|
||
:"color: darkgray;background-color:#e8e8e8 ;"
|
||
).arg(!exitBtn ?
|
||
""
|
||
:
|
||
"background: transparent;"
|
||
"border-radius: 8px;"
|
||
"border: 2px solid transparent;"
|
||
"max-width:1em;"
|
||
"border:none;"
|
||
);
|
||
|
||
QString toolTipStyle=" QToolTip { "
|
||
"border: 1px solid black;"
|
||
"border-width: 1px;"
|
||
"padding: 4px;"
|
||
"font: 14px ; color:black; background-color:yellow;"
|
||
"}";
|
||
btnStyle.append(toolTipStyle);
|
||
return btnStyle;
|
||
}
|
||
|
||
void SaveGraphLayoutSettings::looksOn(QPushButton* button,bool on){
|
||
//button->setEnabled(on);
|
||
button->setStyleSheet(on?styleOn:styleOff);
|
||
}
|
||
|
||
void SaveGraphLayoutSettings::manageButtonApperance() {
|
||
|
||
bool enable = menuList->currentItem();
|
||
looksOn(menuUpdateBtn,enable);
|
||
looksOn(menuRestoreBtn,enable);
|
||
looksOn(menuDeleteBtn,enable);
|
||
looksOn(menuRenameBtn,enable);
|
||
|
||
if (nextNumToUse<0) { // check if at Maximum limit
|
||
// must always hide first
|
||
menuAddBtn->hide();
|
||
menuAddFullBtn->show();
|
||
} else {
|
||
// must always hide first
|
||
menuAddFullBtn->hide();
|
||
menuAddBtn->show();
|
||
}
|
||
}
|
||
|
||
|
||
void SaveGraphLayoutSettings::add_feature() {
|
||
if(!graphView) return;
|
||
QString fileName = QString("%1%2").arg(fileBaseName).arg(nextNumToUse,fileNumMaxLength,10,QLatin1Char('0'));
|
||
writeSettings(fileName);
|
||
// create a default description - use formatted datetime.
|
||
QString desc=QDateTime::currentDateTime().toString();
|
||
descriptionMap->add(fileName,desc);
|
||
descriptionMap->save();
|
||
QListWidgetItem* item = updateFileList( fileName);
|
||
if (item!=nullptr) {
|
||
menuList->setCurrentItem(item,QItemSelectionModel::ClearAndSelect);
|
||
menuList->editItem(item);
|
||
}
|
||
menuList->sortItems();
|
||
resizeMenu();
|
||
}
|
||
|
||
void SaveGraphLayoutSettings::addFull_feature() {
|
||
verifyItem( nullptr,tr("Maximum number of Items exceeded.") , m_icon_add);
|
||
}
|
||
|
||
void SaveGraphLayoutSettings::update_feature() {
|
||
if(!graphView) return;
|
||
QListWidgetItem * item=menuList->currentItem();
|
||
if (!verifyItem(item, tr("No Item Selected") , m_icon_update)) return ;
|
||
if(!confirmAction( item->text(), tr("Ok to Update?") , m_icon_update) ) return;
|
||
QString fileName = item->data(fileNameRole).toString();
|
||
writeSettings(fileName);
|
||
};
|
||
|
||
void SaveGraphLayoutSettings::restore_feature() {
|
||
if(!graphView) return;
|
||
QListWidgetItem * item=menuList->currentItem();
|
||
if (!verifyItem(item, tr("No Item Selected") , m_icon_restore)) return ;
|
||
QString fileName = item->data(fileNameRole).toString();
|
||
loadSettings(fileName);
|
||
closeMenu();
|
||
};
|
||
|
||
void SaveGraphLayoutSettings::rename_feature() {
|
||
if(!graphView) return;
|
||
QListWidgetItem * item=menuList->currentItem();
|
||
if (!verifyItem(item, tr("No Item Selected") , m_icon_rename)) return ;
|
||
menuList->editItem(item);
|
||
// SaveGraphLayoutSettings::itemChanged(QListWidgetItem *item) is called when edit changes the entry.
|
||
// itemChanged will update the description map
|
||
}
|
||
|
||
void SaveGraphLayoutSettings::help_exit_feature() {
|
||
closeMenu();
|
||
closeHelp();
|
||
}
|
||
|
||
void SaveGraphLayoutSettings::help_feature() {
|
||
initminMenuListSize();
|
||
createHelp();
|
||
if(!help.dialog) return;
|
||
if (help.open) {
|
||
closeHelp();
|
||
return;
|
||
}
|
||
help.dialog->raise();
|
||
help.open=true;
|
||
help.dialog->exec();
|
||
help.open=false;
|
||
manageButtonApperance();
|
||
}
|
||
|
||
void SaveGraphLayoutSettings::delete_feature() {
|
||
if(!graphView) return;
|
||
QListWidgetItem * item=menuList->currentItem();
|
||
if (!verifyItem(item, tr("No Item Selected") , m_icon_delete)) return ;
|
||
if(!confirmAction(item->text(), tr("Ok To Delete?") ,m_icon_delete) ) return;
|
||
|
||
QString fileName = item->data(fileNameRole).toString();
|
||
descriptionMap->remove(fileName);
|
||
descriptionMap->save();
|
||
deleteSettings(fileName);
|
||
delete item;
|
||
if (nextNumToUse<0) {
|
||
nextNumToUse=fileNum(fileName);
|
||
}
|
||
manageButtonApperance();
|
||
resizeMenu();
|
||
}
|
||
|
||
void SaveGraphLayoutSettings::itemChanged(QListWidgetItem *item)
|
||
{
|
||
QString fileName=item->data(fileNameRole).toString();
|
||
QString desc= item->text();
|
||
|
||
// use only the first line in a multiline string. Can be set using cut and paste
|
||
QRegularExpressionMatch match = singleLineRe->match(desc);
|
||
if (match.hasMatch()) {
|
||
// captured match is the first line and has been truncated
|
||
desc=match.captured(1).trimmed(); // reoves spaces at end.
|
||
} else {
|
||
// no match.
|
||
// an invalid name was entered. too much white space or empty
|
||
desc="";
|
||
}
|
||
if (desc.length()>maxDescriptionLen) {
|
||
desc.append("...");
|
||
}
|
||
if (desc.length() <=0) {
|
||
// returns name back to previous saved name
|
||
desc=descriptionMap->get(fileName);
|
||
} else {
|
||
descriptionMap->add(fileName,desc);
|
||
descriptionMap->save();
|
||
}
|
||
item->setText(desc);
|
||
menuList->sortItems();
|
||
menuList->setCurrentItem(item);
|
||
resizeMenu();
|
||
|
||
}
|
||
|
||
void SaveGraphLayoutSettings::itemSelectionChanged()
|
||
{
|
||
initminMenuListSize();
|
||
manageButtonApperance();
|
||
}
|
||
|
||
void SaveGraphLayoutSettings::initminMenuListSize() {
|
||
if (minMenuDialogSize.width()==0) {
|
||
menuDialogSize = menu.dialog->size();
|
||
minMenuDialogSize = menuDialogSize;
|
||
|
||
menuListSize = menuList->size();
|
||
minMenuListSize = menuListSize;
|
||
|
||
dialogListDiff = menuDialogSize - menuListSize;
|
||
|
||
dialogListDiff.setWidth (horizontalWidthAdjustment + dialogListDiff.width());
|
||
|
||
resizeMenu();
|
||
}
|
||
};
|
||
|
||
void SaveGraphLayoutSettings::writeSettings(QString filename) {
|
||
graphView->SaveSettings(title+"."+filename,dirName);
|
||
};
|
||
|
||
void SaveGraphLayoutSettings::loadSettings(QString filename) {
|
||
graphView->LoadSettings(title+"."+filename,dirName);
|
||
};
|
||
|
||
void SaveGraphLayoutSettings::deleteSettings(QString filename) {
|
||
QString fileName=graphView->settingsFilename (title+"."+filename,dirName) ;
|
||
dir->remove(fileName);
|
||
};
|
||
|
||
int SaveGraphLayoutSettings::fileNum(QString fileName) {
|
||
QRegularExpressionMatch match = fileNumRe->match(fileName);
|
||
int value=-1;
|
||
if (match.hasMatch()) {
|
||
value=match.captured(1).toInt();
|
||
}
|
||
return value;
|
||
}
|
||
|
||
|
||
QSize SaveGraphLayoutSettings::maxSize(const QSize AA , const QSize BB ) {
|
||
return QSize ( qMax(AA.width(),BB.width()) , qMax(AA.height(),BB.height() ) );
|
||
}
|
||
|
||
bool SaveGraphLayoutSettings::sizeEqual(const QSize AA , const QSize BB ) {
|
||
return (AA.width()==BB.width()) && ( AA.height()==BB.height()) ;
|
||
}
|
||
|
||
|
||
|
||
void SaveGraphLayoutSettings::resizeMenu() {
|
||
if (minMenuDialogSize.width()==0) return;
|
||
|
||
QSize newSize = calculateMenuDialogSize();
|
||
newSize.setWidth ( newSize.width());
|
||
|
||
menuDialogSize = menu.dialog->size();
|
||
|
||
if ( sizeEqual(newSize , menuDialogSize)) {
|
||
// no work to do
|
||
return;
|
||
};
|
||
|
||
if ( menuDialogSize.width() < newSize.width() ) {
|
||
menu.dialog->setMinimumWidth(newSize.width());
|
||
menu.dialog->setMaximumWidth(QWIDGETSIZE_MAX);
|
||
} else if ( menuDialogSize.width() > newSize.width() ) {
|
||
menu.dialog->setMaximumWidth(newSize.width());
|
||
menu.dialog->setMinimumWidth(newSize.width());
|
||
}
|
||
if ( menuDialogSize.height() < newSize.height() ) {
|
||
menu.dialog->setMinimumHeight(newSize.height());
|
||
menu.dialog->setMaximumHeight(QWIDGETSIZE_MAX);
|
||
} else if ( menuDialogSize.height() > newSize.height() ) {
|
||
menu.dialog->setMaximumHeight(newSize.height());
|
||
menu.dialog->setMinimumHeight(newSize.height());
|
||
}
|
||
menuDialogSize = newSize;
|
||
}
|
||
|
||
QSize SaveGraphLayoutSettings::calculateMenuDialogSize() {
|
||
if (menuDialogSize.width()==0) return QSize(0,0);
|
||
QListWidgetItem* item;
|
||
widestItem=nullptr;
|
||
QFontMetrics fm = QFontMetrics(menu.font);
|
||
|
||
// account for scrollbars.
|
||
QSize returnValue = QSize( 0 , fm.height() ); // add an extra space at the bottom. width didn't work
|
||
|
||
// Account for dialog Size
|
||
returnValue += dialogListDiff;
|
||
QSize size;
|
||
|
||
for (int index = 0; index < menuList->count(); ++index) {
|
||
item = menuList->item(index);
|
||
if (!item) continue;
|
||
size = fm.boundingRect(item->text()).size();
|
||
if (returnValue.width() < size.width()) {
|
||
returnValue.setWidth( qMax( returnValue.width(),size.width()));
|
||
widestItem=item;
|
||
}
|
||
returnValue.setHeight( returnValue.height()+size.height());
|
||
}
|
||
returnValue.setWidth( horizontalWidthAdjustment + returnValue.width() ) ;
|
||
|
||
returnValue = maxSize(returnValue, minMenuDialogSize);
|
||
return returnValue;
|
||
}
|
||
|
||
QListWidgetItem* SaveGraphLayoutSettings::updateFileList(QString find) {
|
||
QListWidgetItem* ret=nullptr;
|
||
manageButtonApperance();
|
||
dir->refresh();
|
||
QFileInfoList filelist = dir->entryInfoList( QDir::Files | QDir::Readable | QDir::Writable | QDir::NoSymLinks,QDir::Name);
|
||
|
||
// Restrict number of files. easy to find availble unused entry for add function.
|
||
|
||
int row=0;
|
||
int count=0;
|
||
menuList->clear();
|
||
nextNumToUse=-1;
|
||
descriptionMap->load();
|
||
for (int i = 0; i < filelist.size(); ++i) {
|
||
QFileInfo fileInfo = filelist.at(i);
|
||
QString fileName = fileInfo.fileName();
|
||
QRegularExpressionMatch match = parseFilenameRe->match(fileName);
|
||
if (match.hasMatch()) {
|
||
if (match.lastCapturedIndex()==3) {
|
||
QString fileName=match.captured(2);
|
||
if (nextNumToUse<0) {
|
||
// check if an entry is availavle to use
|
||
int fileNum=match.captured(3).toInt();
|
||
// find an available file name(number);
|
||
if (fileNum!=count) {
|
||
nextNumToUse=count;
|
||
}
|
||
}
|
||
count++;
|
||
|
||
QListWidgetItem *item = new QListWidgetItem(descriptionMap->get(fileName));
|
||
item->setData(fileNameRole,fileName);
|
||
item->setFlags(item->flags() | Qt::ItemIsEditable);
|
||
menuList->insertItem(row,item);
|
||
row++;
|
||
if (find!=nullptr && fileName==find) {
|
||
ret=item;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (nextNumToUse<0) { // check if there is an existing empty slot
|
||
// if not then the next available slot is at the end. CHeck if at max files.
|
||
if (count<maxFiles) {
|
||
// a slot is available
|
||
nextNumToUse=count;
|
||
}
|
||
}
|
||
manageButtonApperance();
|
||
menuList->sortItems();
|
||
return ret;
|
||
}
|
||
|
||
|
||
void SaveGraphLayoutSettings::closeHelp() {
|
||
if (help.open) {
|
||
help.dialog->close();
|
||
}
|
||
}
|
||
|
||
void SaveGraphLayoutSettings::closeHint() {
|
||
if (hint.open) {
|
||
hint.dialog->close();
|
||
}
|
||
}
|
||
|
||
void SaveGraphLayoutSettings::closeMenu() {
|
||
closeHelp();
|
||
closeHint();
|
||
if (menu.open) {
|
||
menu.dialog->close();
|
||
}
|
||
}
|
||
|
||
void SaveGraphLayoutSettings::triggerLayout(gGraphView* graphView) {
|
||
if (dir==nullptr) {
|
||
//const char* err=qPrintable(QString("Cannot find directory %1").arg(dirName));
|
||
//qWarning(err);
|
||
return;
|
||
}
|
||
if (menu.open) {
|
||
closeMenu();
|
||
return;
|
||
}
|
||
this->graphView=graphView;
|
||
updateFileList();
|
||
manageButtonApperance();
|
||
menu.dialog->raise();
|
||
menu.open=true;
|
||
menu.dialog->exec();
|
||
menu.open=false;
|
||
closeMenu();
|
||
}
|
||
|
||
QSize textsize(QFont font ,QString text) {
|
||
return QFontMetrics(font).size(0 , text);
|
||
}
|
||
|
||
void SaveGraphLayoutSettings::createHint() {
|
||
createHelp(hint, tr("Graph Short-Cuts Help"), hintInfo());
|
||
if (hint.exitBtn) {
|
||
hint.dialog->connect(hint.exitBtn, SIGNAL(clicked()), this, SLOT (closeHint()));
|
||
}
|
||
};
|
||
|
||
void SaveGraphLayoutSettings::hintHelp() {
|
||
if (hint.open) {
|
||
hint.dialog->close();
|
||
return;
|
||
}
|
||
createHint();
|
||
if (!hint.dialog) return;
|
||
|
||
hint.dialog->raise();
|
||
hint.dialog->show();
|
||
hint.open=true;
|
||
hint.dialog->exec();
|
||
hint.open=false;
|
||
}
|
||
|
||
|
||
//====================================================================================================
|
||
//====================================================================================================
|
||
// Descriptions map class with file storage
|
||
|
||
DescriptionMap::DescriptionMap(QDir* dir, QString _filename)
|
||
{
|
||
filename = dir->absoluteFilePath(_filename);
|
||
parseDescriptionsRe = new QRegularExpression(QString("^\\s*(\\w+)%1(.*)$").arg(delimiter) );
|
||
};
|
||
|
||
DescriptionMap::~DescriptionMap() {
|
||
delete parseDescriptionsRe;
|
||
};
|
||
|
||
void DescriptionMap::add(QString key,QString desc) {
|
||
descriptions.insert(key,desc);
|
||
};
|
||
|
||
void DescriptionMap::remove(QString key) {
|
||
descriptions.remove(key);
|
||
}
|
||
QString DescriptionMap::get(QString key) {
|
||
QString ret =descriptions.value(key,key);
|
||
return ret;
|
||
}
|
||
|
||
void DescriptionMap::save() {
|
||
QFile file(filename);
|
||
file.open(QFile::WriteOnly);
|
||
QTextStream out(&file);
|
||
QMapIterator<QString, QString>it(descriptions);
|
||
while (it.hasNext()) {
|
||
it.next();
|
||
QString line=QString("%1%2%3\n").arg(it.key()).arg(delimiter).arg(it.value());
|
||
out <<line;
|
||
}
|
||
file.close();
|
||
}
|
||
|
||
void DescriptionMap::load() {
|
||
QString line;
|
||
QFile file(filename);
|
||
descriptions.clear();
|
||
if (!file.exists()) return;
|
||
file.open(QFile::ReadOnly);
|
||
QTextStream instr(&file);
|
||
while (instr.readLineInto(&line)) {
|
||
QRegularExpressionMatch match = parseDescriptionsRe->match(line);
|
||
if (match.hasMatch()) {
|
||
QString fileName = match.captured(1);
|
||
QString desc = match.captured(2);
|
||
add(fileName,desc);
|
||
} else {
|
||
DEBUGF QQ("MATCH ERROR",line);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
//====================================================================================================
|
||
//====================================================================================================
|
||
|
||
|
||
#if 0
|
||
|
||
Different languages unicodes to test. optained from translation files
|
||
|
||
도움주신분들
|
||
已成功删除
|
||
删除
|
||
הצג את מחיצת הנתונים
|
||
|
||
הצג את מחיצת הנתונים 已成功删除 عذرا ، لا يمكن تحديد موقع ملف.
|
||
已成功删除 عذرا ، لا يمكن تحديد موقع ملف. 删除
|
||
Toon gegevensmap
|
||
عذرا ، لا يمكن تحديد موقع ملف.
|
||
|
||
#endif
|