Fixed #81.
This commit is contained in:
		
							parent
							
								
									e99b66f9eb
								
							
						
					
					
						commit
						7bc8caa6c4
					
				
					 9 changed files with 161 additions and 102 deletions
				
			
		| 
						 | 
					@ -2,6 +2,7 @@
 | 
				
			||||||
—————
 | 
					—————
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Added:
 | 
					Added:
 | 
				
			||||||
 | 
					▪ User now can place custom user skins in user "data" folder. (issue #81) See "About" dialog for the exact path.
 | 
				
			||||||
▪ User now can select if DB transactions are enabled or not. (bug #70) By default, DB transactions are now switched OFF, therefore anyone who wants better performance, must turn them ON in app settings.
 | 
					▪ User now can select if DB transactions are enabled or not. (bug #70) By default, DB transactions are now switched OFF, therefore anyone who wants better performance, must turn them ON in app settings.
 | 
				
			||||||
▪ MySQL database backend now requires at least version 5.5, DB encoding is now changed to utf8mb4 character set. (bug #74)
 | 
					▪ MySQL database backend now requires at least version 5.5, DB encoding is now changed to utf8mb4 character set. (bug #74)
 | 
				
			||||||
▪ Height if message attachment image is now configurable, defaults to 36. (issue #69)
 | 
					▪ Height if message attachment image is now configurable, defaults to 36. (issue #69)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -105,24 +105,21 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define APP_DB_SQLITE_DRIVER          "QSQLITE"
 | 
					#define APP_DB_SQLITE_DRIVER          "QSQLITE"
 | 
				
			||||||
#define APP_DB_SQLITE_INIT            "db_init_sqlite.sql"
 | 
					#define APP_DB_SQLITE_INIT            "db_init_sqlite.sql"
 | 
				
			||||||
#define APP_DB_SQLITE_PATH            "data/database/local"
 | 
					#define APP_DB_SQLITE_PATH            "database/local"
 | 
				
			||||||
#define APP_DB_SQLITE_FILE            "database.db"
 | 
					#define APP_DB_SQLITE_FILE            "database.db"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Keep this in sync with schema versions declared in SQL initialization code.
 | 
					// Keep this in sync with schema versions declared in SQL initialization code.
 | 
				
			||||||
#define APP_DB_SCHEMA_VERSION         "7"
 | 
					#define APP_DB_SCHEMA_VERSION         "7"
 | 
				
			||||||
#define APP_DB_UPDATE_FILE_PATTERN    "db_update_%1_%2_%3.sql"
 | 
					#define APP_DB_UPDATE_FILE_PATTERN    "db_update_%1_%2_%3.sql"
 | 
				
			||||||
#define APP_DB_COMMENT_SPLIT          "-- !\n"
 | 
					#define APP_DB_COMMENT_SPLIT          "-- !\n"
 | 
				
			||||||
#define APP_DB_WEB_PATH               "data/database/web"
 | 
					 | 
				
			||||||
#define APP_DB_NAME_PLACEHOLDER       "##"
 | 
					#define APP_DB_NAME_PLACEHOLDER       "##"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define APP_CFG_PATH        "data/config"
 | 
					#define APP_CFG_PATH        "config"
 | 
				
			||||||
#define APP_CFG_FILE        "config.ini"
 | 
					#define APP_CFG_FILE        "config.ini"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define APP_LOG_PATH        "data/log"
 | 
					 | 
				
			||||||
#define APP_LOG_FILE        "log.txt"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define APP_QUIT_INSTANCE   "-q"
 | 
					#define APP_QUIT_INSTANCE   "-q"
 | 
				
			||||||
#define APP_IS_RUNNING      "app_is_running"
 | 
					#define APP_IS_RUNNING      "app_is_running"
 | 
				
			||||||
 | 
					#define APP_SKIN_USER_FOLDER "skins"
 | 
				
			||||||
#define APP_SKIN_DEFAULT    "vergilius"
 | 
					#define APP_SKIN_DEFAULT    "vergilius"
 | 
				
			||||||
#define APP_SKIN_METADATA_FILE "metadata.xml"
 | 
					#define APP_SKIN_METADATA_FILE "metadata.xml"
 | 
				
			||||||
#define APP_STYLE_DEFAULT   "Fusion"
 | 
					#define APP_STYLE_DEFAULT   "Fusion"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,20 +51,16 @@ FormAbout::~FormAbout() {
 | 
				
			||||||
void FormAbout::loadSettingsAndPaths() {
 | 
					void FormAbout::loadSettingsAndPaths() {
 | 
				
			||||||
  if (qApp->settings()->type() == SettingsProperties::Portable) {
 | 
					  if (qApp->settings()->type() == SettingsProperties::Portable) {
 | 
				
			||||||
    m_ui->m_txtPathsSettingsType->setText(tr("FULLY portable"));
 | 
					    m_ui->m_txtPathsSettingsType->setText(tr("FULLY portable"));
 | 
				
			||||||
    m_ui->m_txtPathsDatabaseRoot->setText(QDir::toNativeSeparators(qApp->applicationDirPath() +
 | 
					 | 
				
			||||||
                                                                   QDir::separator() +
 | 
					 | 
				
			||||||
                                                                   QString(APP_DB_SQLITE_PATH)));
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  else {
 | 
					  else {
 | 
				
			||||||
    m_ui->m_txtPathsSettingsType->setText(tr("PARTIALLY portable"));
 | 
					    m_ui->m_txtPathsSettingsType->setText(tr("PARTIALLY portable"));
 | 
				
			||||||
    m_ui->m_txtPathsDatabaseRoot->setText(QDir::toNativeSeparators(qApp->homeFolderPath() +
 | 
					 | 
				
			||||||
                                                                   QDir::separator() +
 | 
					 | 
				
			||||||
                                                                   QString(APP_LOW_H_NAME) +
 | 
					 | 
				
			||||||
                                                                   QDir::separator() +
 | 
					 | 
				
			||||||
                                                                   QString(APP_DB_SQLITE_PATH)));
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  m_ui->m_txtPathsDatabaseRoot->setText(QDir::toNativeSeparators(qApp->settings()->userSettingsRootFolder() +
 | 
				
			||||||
 | 
					                                                                 QDir::separator() +
 | 
				
			||||||
 | 
					                                                                 QString(APP_DB_SQLITE_PATH)));
 | 
				
			||||||
  m_ui->m_txtPathsSettingsFile->setText(QDir::toNativeSeparators(qApp->settings()->fileName()));
 | 
					  m_ui->m_txtPathsSettingsFile->setText(QDir::toNativeSeparators(qApp->settings()->fileName()));
 | 
				
			||||||
 | 
					  m_ui->m_txtPathsSkinsRoot->setText(QDir::toNativeSeparators(qApp->skins()->getUserSkinBaseFolder()));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void FormAbout::loadLicenseAndInformation() {
 | 
					void FormAbout::loadLicenseAndInformation() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -92,7 +92,7 @@
 | 
				
			||||||
      <locale language="English" country="UnitedStates"/>
 | 
					      <locale language="English" country="UnitedStates"/>
 | 
				
			||||||
     </property>
 | 
					     </property>
 | 
				
			||||||
     <property name="currentIndex">
 | 
					     <property name="currentIndex">
 | 
				
			||||||
      <number>0</number>
 | 
					      <number>3</number>
 | 
				
			||||||
     </property>
 | 
					     </property>
 | 
				
			||||||
     <widget class="QWidget" name="m_tabInfo">
 | 
					     <widget class="QWidget" name="m_tabInfo">
 | 
				
			||||||
      <attribute name="title">
 | 
					      <attribute name="title">
 | 
				
			||||||
| 
						 | 
					@ -125,7 +125,7 @@
 | 
				
			||||||
          <string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
 | 
					          <string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
 | 
				
			||||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
 | 
					<html><head><meta name="qrichtext" content="1" /><style type="text/css">
 | 
				
			||||||
p, li { white-space: pre-wrap; }
 | 
					p, li { white-space: pre-wrap; }
 | 
				
			||||||
</style></head><body style=" font-family:'DejaVu Sans Mono'; font-size:10pt; font-weight:400; font-style:normal;">
 | 
					</style></head><body style=" font-family:'DejaVu Sans Mono'; font-size:8.25pt; font-weight:400; font-style:normal;">
 | 
				
			||||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></string>
 | 
					<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></string>
 | 
				
			||||||
         </property>
 | 
					         </property>
 | 
				
			||||||
         <property name="acceptRichText">
 | 
					         <property name="acceptRichText">
 | 
				
			||||||
| 
						 | 
					@ -159,8 +159,8 @@ p, li { white-space: pre-wrap; }
 | 
				
			||||||
           <rect>
 | 
					           <rect>
 | 
				
			||||||
            <x>0</x>
 | 
					            <x>0</x>
 | 
				
			||||||
            <y>0</y>
 | 
					            <y>0</y>
 | 
				
			||||||
            <width>98</width>
 | 
					            <width>685</width>
 | 
				
			||||||
            <height>73</height>
 | 
					            <height>184</height>
 | 
				
			||||||
           </rect>
 | 
					           </rect>
 | 
				
			||||||
          </property>
 | 
					          </property>
 | 
				
			||||||
          <property name="autoFillBackground">
 | 
					          <property name="autoFillBackground">
 | 
				
			||||||
| 
						 | 
					@ -217,7 +217,7 @@ p, li { white-space: pre-wrap; }
 | 
				
			||||||
              <string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
 | 
					              <string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
 | 
				
			||||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
 | 
					<html><head><meta name="qrichtext" content="1" /><style type="text/css">
 | 
				
			||||||
p, li { white-space: pre-wrap; }
 | 
					p, li { white-space: pre-wrap; }
 | 
				
			||||||
</style></head><body style=" font-family:'DejaVu Sans Mono'; font-size:10pt; font-weight:400; font-style:normal;">
 | 
					</style></head><body style=" font-family:'DejaVu Sans Mono'; font-size:8.25pt; font-weight:400; font-style:normal;">
 | 
				
			||||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></string>
 | 
					<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></string>
 | 
				
			||||||
             </property>
 | 
					             </property>
 | 
				
			||||||
             <property name="textInteractionFlags">
 | 
					             <property name="textInteractionFlags">
 | 
				
			||||||
| 
						 | 
					@ -235,8 +235,8 @@ p, li { white-space: pre-wrap; }
 | 
				
			||||||
           <rect>
 | 
					           <rect>
 | 
				
			||||||
            <x>0</x>
 | 
					            <x>0</x>
 | 
				
			||||||
            <y>0</y>
 | 
					            <y>0</y>
 | 
				
			||||||
            <width>98</width>
 | 
					            <width>83</width>
 | 
				
			||||||
            <height>73</height>
 | 
					            <height>69</height>
 | 
				
			||||||
           </rect>
 | 
					           </rect>
 | 
				
			||||||
          </property>
 | 
					          </property>
 | 
				
			||||||
          <attribute name="label">
 | 
					          <attribute name="label">
 | 
				
			||||||
| 
						 | 
					@ -287,7 +287,7 @@ p, li { white-space: pre-wrap; }
 | 
				
			||||||
              <string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
 | 
					              <string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
 | 
				
			||||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
 | 
					<html><head><meta name="qrichtext" content="1" /><style type="text/css">
 | 
				
			||||||
p, li { white-space: pre-wrap; }
 | 
					p, li { white-space: pre-wrap; }
 | 
				
			||||||
</style></head><body style=" font-family:'DejaVu Sans Mono'; font-size:10pt; font-weight:400; font-style:normal;">
 | 
					</style></head><body style=" font-family:'DejaVu Sans Mono'; font-size:8.25pt; font-weight:400; font-style:normal;">
 | 
				
			||||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></string>
 | 
					<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></string>
 | 
				
			||||||
             </property>
 | 
					             </property>
 | 
				
			||||||
             <property name="textInteractionFlags">
 | 
					             <property name="textInteractionFlags">
 | 
				
			||||||
| 
						 | 
					@ -333,7 +333,7 @@ p, li { white-space: pre-wrap; }
 | 
				
			||||||
          <string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
 | 
					          <string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
 | 
				
			||||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
 | 
					<html><head><meta name="qrichtext" content="1" /><style type="text/css">
 | 
				
			||||||
p, li { white-space: pre-wrap; }
 | 
					p, li { white-space: pre-wrap; }
 | 
				
			||||||
</style></head><body style=" font-family:'DejaVu Sans Mono'; font-size:10pt; font-weight:400; font-style:normal;">
 | 
					</style></head><body style=" font-family:'DejaVu Sans Mono'; font-size:8.25pt; font-weight:400; font-style:normal;">
 | 
				
			||||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></string>
 | 
					<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></string>
 | 
				
			||||||
         </property>
 | 
					         </property>
 | 
				
			||||||
         <property name="acceptRichText">
 | 
					         <property name="acceptRichText">
 | 
				
			||||||
| 
						 | 
					@ -389,20 +389,34 @@ p, li { white-space: pre-wrap; }
 | 
				
			||||||
         </property>
 | 
					         </property>
 | 
				
			||||||
        </widget>
 | 
					        </widget>
 | 
				
			||||||
       </item>
 | 
					       </item>
 | 
				
			||||||
 | 
					       <item row="2" column="1">
 | 
				
			||||||
 | 
					        <widget class="QLineEdit" name="m_txtPathsDatabaseRoot">
 | 
				
			||||||
 | 
					         <property name="readOnly">
 | 
				
			||||||
 | 
					          <bool>true</bool>
 | 
				
			||||||
 | 
					         </property>
 | 
				
			||||||
 | 
					        </widget>
 | 
				
			||||||
 | 
					       </item>
 | 
				
			||||||
       <item row="2" column="0">
 | 
					       <item row="2" column="0">
 | 
				
			||||||
        <widget class="QLabel" name="label_3">
 | 
					        <widget class="QLabel" name="label_4">
 | 
				
			||||||
         <property name="text">
 | 
					         <property name="text">
 | 
				
			||||||
          <string>Database root path</string>
 | 
					          <string>Database root path</string>
 | 
				
			||||||
         </property>
 | 
					         </property>
 | 
				
			||||||
        </widget>
 | 
					        </widget>
 | 
				
			||||||
       </item>
 | 
					       </item>
 | 
				
			||||||
       <item row="2" column="1">
 | 
					       <item row="3" column="1">
 | 
				
			||||||
        <widget class="QLineEdit" name="m_txtPathsDatabaseRoot">
 | 
					        <widget class="QLineEdit" name="m_txtPathsSkinsRoot">
 | 
				
			||||||
         <property name="readOnly">
 | 
					         <property name="readOnly">
 | 
				
			||||||
          <bool>true</bool>
 | 
					          <bool>true</bool>
 | 
				
			||||||
         </property>
 | 
					         </property>
 | 
				
			||||||
        </widget>
 | 
					        </widget>
 | 
				
			||||||
       </item>
 | 
					       </item>
 | 
				
			||||||
 | 
					       <item row="3" column="0">
 | 
				
			||||||
 | 
					        <widget class="QLabel" name="label_3">
 | 
				
			||||||
 | 
					         <property name="text">
 | 
				
			||||||
 | 
					          <string>User skins root path</string>
 | 
				
			||||||
 | 
					         </property>
 | 
				
			||||||
 | 
					        </widget>
 | 
				
			||||||
 | 
					       </item>
 | 
				
			||||||
      </layout>
 | 
					      </layout>
 | 
				
			||||||
     </widget>
 | 
					     </widget>
 | 
				
			||||||
    </widget>
 | 
					    </widget>
 | 
				
			||||||
| 
						 | 
					@ -416,6 +430,17 @@ p, li { white-space: pre-wrap; }
 | 
				
			||||||
   </item>
 | 
					   </item>
 | 
				
			||||||
  </layout>
 | 
					  </layout>
 | 
				
			||||||
 </widget>
 | 
					 </widget>
 | 
				
			||||||
 | 
					 <tabstops>
 | 
				
			||||||
 | 
					  <tabstop>m_tabAbout</tabstop>
 | 
				
			||||||
 | 
					  <tabstop>m_txtPathsSettingsType</tabstop>
 | 
				
			||||||
 | 
					  <tabstop>m_txtPathsSettingsFile</tabstop>
 | 
				
			||||||
 | 
					  <tabstop>m_txtPathsDatabaseRoot</tabstop>
 | 
				
			||||||
 | 
					  <tabstop>m_txtPathsSkinsRoot</tabstop>
 | 
				
			||||||
 | 
					  <tabstop>m_txtInfo</tabstop>
 | 
				
			||||||
 | 
					  <tabstop>m_txtLicenseGnu</tabstop>
 | 
				
			||||||
 | 
					  <tabstop>m_txtChangelog</tabstop>
 | 
				
			||||||
 | 
					  <tabstop>m_txtLicenseBsd</tabstop>
 | 
				
			||||||
 | 
					 </tabstops>
 | 
				
			||||||
 <resources/>
 | 
					 <resources/>
 | 
				
			||||||
 <connections>
 | 
					 <connections>
 | 
				
			||||||
  <connection>
 | 
					  <connection>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -187,14 +187,7 @@ void DatabaseFactory::finishRestoration() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void DatabaseFactory::sqliteAssemblyDatabaseFilePath()  {
 | 
					void DatabaseFactory::sqliteAssemblyDatabaseFilePath()  {
 | 
				
			||||||
  if (qApp->settings()->type() == SettingsProperties::Portable) {
 | 
					  m_sqliteDatabaseFilePath = qApp->settings()->userSettingsRootFolder() + QDir::separator() + QString(APP_DB_SQLITE_PATH);
 | 
				
			||||||
    m_sqliteDatabaseFilePath = qApp->applicationDirPath() + QDir::separator() + QString(APP_DB_SQLITE_PATH);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  else {
 | 
					 | 
				
			||||||
    m_sqliteDatabaseFilePath = qApp->homeFolderPath() + QDir::separator() +
 | 
					 | 
				
			||||||
                               QString(APP_LOW_H_NAME) + QDir::separator() +
 | 
					 | 
				
			||||||
                               QString(APP_DB_SQLITE_PATH);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QSqlDatabase DatabaseFactory::sqliteInitializeInMemoryDatabase() {
 | 
					QSqlDatabase DatabaseFactory::sqliteInitializeInMemoryDatabase() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -275,6 +275,15 @@ Settings::Settings(const QString &file_name, Format format, const SettingsProper
 | 
				
			||||||
Settings::~Settings() {  
 | 
					Settings::~Settings() {  
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QString Settings::userSettingsRootFolder() const {
 | 
				
			||||||
 | 
					  if (qApp->settings()->type() == SettingsProperties::Portable) {
 | 
				
			||||||
 | 
					    return getAppPathUserFolder();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else {
 | 
				
			||||||
 | 
					    return getHomeUserFolder();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QString Settings::pathName() const {
 | 
					QString Settings::pathName() const {
 | 
				
			||||||
  return QFileInfo(fileName()).absolutePath();
 | 
					  return QFileInfo(fileName()).absolutePath();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -309,6 +318,14 @@ void Settings::finishRestoration(const QString &desired_settings_file_path) {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QString Settings::getAppPathUserFolder() {
 | 
				
			||||||
 | 
					  return qApp->applicationDirPath() + QDir::separator() + QSL("data");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QString Settings::getHomeUserFolder() {
 | 
				
			||||||
 | 
					  return qApp->homeFolderPath() + QDir::separator() + QString(APP_LOW_H_NAME) + QDir::separator() + QSL("data");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Settings *Settings::setupSettings(QObject *parent) {
 | 
					Settings *Settings::setupSettings(QObject *parent) {
 | 
				
			||||||
  Settings *new_settings;
 | 
					  Settings *new_settings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -338,11 +355,12 @@ SettingsProperties Settings::determineProperties() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  properties.m_settingsSuffix = QDir::separator() + QString(APP_CFG_PATH) + QDir::separator() + QString(APP_CFG_FILE);
 | 
					  properties.m_settingsSuffix = QDir::separator() + QString(APP_CFG_PATH) + QDir::separator() + QString(APP_CFG_FILE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const QString app_path = qApp->applicationDirPath();
 | 
					  const QString exe_path = qApp->applicationDirPath();
 | 
				
			||||||
  const QString home_path = qApp->homeFolderPath() + QDir::separator() + QString(APP_LOW_H_NAME);
 | 
					  const QString app_path = getAppPathUserFolder();
 | 
				
			||||||
 | 
					  const QString home_path =  getHomeUserFolder();
 | 
				
			||||||
  const QString home_path_file = home_path + properties.m_settingsSuffix;
 | 
					  const QString home_path_file = home_path + properties.m_settingsSuffix;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const bool portable_settings_available = IOFactory::isFolderWritable(app_path);
 | 
					  const bool portable_settings_available = IOFactory::isFolderWritable(exe_path);
 | 
				
			||||||
  const bool non_portable_settings_exist = QFile::exists(home_path_file);
 | 
					  const bool non_portable_settings_exist = QFile::exists(home_path_file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // We will use PORTABLE settings only and only if it is available and NON-PORTABLE
 | 
					  // We will use PORTABLE settings only and only if it is available and NON-PORTABLE
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -312,6 +312,9 @@ class Settings : public QSettings {
 | 
				
			||||||
      return m_initializationStatus;
 | 
					      return m_initializationStatus;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Returns the base folder to which store user data, the "data" folder.
 | 
				
			||||||
 | 
					    QString userSettingsRootFolder() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Getters/setters for settings values.
 | 
					    // Getters/setters for settings values.
 | 
				
			||||||
    inline QVariant value(const QString §ion, const QString &key, const QVariant &default_value = QVariant()) const {
 | 
					    inline QVariant value(const QString §ion, const QString &key, const QVariant &default_value = QVariant()) const {
 | 
				
			||||||
      return QSettings::value(QString("%1/%2").arg(section, key), default_value);
 | 
					      return QSettings::value(QString("%1/%2").arg(section, key), default_value);
 | 
				
			||||||
| 
						 | 
					@ -342,6 +345,9 @@ class Settings : public QSettings {
 | 
				
			||||||
    bool initiateRestoration(const QString &settings_backup_file_path);
 | 
					    bool initiateRestoration(const QString &settings_backup_file_path);
 | 
				
			||||||
    static void finishRestoration(const QString &desired_settings_file_path);
 | 
					    static void finishRestoration(const QString &desired_settings_file_path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static QString getAppPathUserFolder();
 | 
				
			||||||
 | 
					    static QString getHomeUserFolder();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Creates settings file in correct location.
 | 
					    // Creates settings file in correct location.
 | 
				
			||||||
    static Settings *setupSettings(QObject *parent);
 | 
					    static Settings *setupSettings(QObject *parent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,7 +65,6 @@ void SkinFactory::loadCurrentSkin() {
 | 
				
			||||||
void SkinFactory::loadSkinFromData(const Skin &skin) {  
 | 
					void SkinFactory::loadSkinFromData(const Skin &skin) {  
 | 
				
			||||||
  if (!skin.m_rawData.isEmpty()) {
 | 
					  if (!skin.m_rawData.isEmpty()) {
 | 
				
			||||||
    qApp->setStyleSheet(skin.m_rawData);
 | 
					    qApp->setStyleSheet(skin.m_rawData);
 | 
				
			||||||
    //qApp->setStyleSheet("QWidget {rgb(39, 43, 48);}");
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  qApp->setStyle(qApp->settings()->value(GROUP(GUI), SETTING(GUI::Style)).toString());
 | 
					  qApp->setStyle(qApp->settings()->value(GROUP(GUI), SETTING(GUI::Style)).toString());
 | 
				
			||||||
| 
						 | 
					@ -75,74 +74,91 @@ void SkinFactory::setCurrentSkinName(const QString &skin_name) {
 | 
				
			||||||
  qApp->settings()->setValue(GROUP(GUI), GUI::Skin, skin_name);
 | 
					  qApp->settings()->setValue(GROUP(GUI), GUI::Skin, skin_name);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QString SkinFactory::getUserSkinBaseFolder() const {
 | 
				
			||||||
 | 
					  return qApp->settings()->userSettingsRootFolder() + QDir::separator() + APP_SKIN_USER_FOLDER;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QString SkinFactory::selectedSkinName() const {
 | 
					QString SkinFactory::selectedSkinName() const {
 | 
				
			||||||
  return qApp->settings()->value(GROUP(GUI), SETTING(GUI::Skin)).toString();
 | 
					  return qApp->settings()->value(GROUP(GUI), SETTING(GUI::Skin)).toString();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Skin SkinFactory::skinInfo(const QString &skin_name, bool *ok) const {
 | 
					Skin SkinFactory::skinInfo(const QString &skin_name, bool *ok) const {
 | 
				
			||||||
  Skin skin;
 | 
					  Skin skin;
 | 
				
			||||||
  QFile skin_file(APP_SKIN_PATH + QDir::separator() + skin_name + QDir::separator() + APP_SKIN_METADATA_FILE);
 | 
					  QStringList base_skin_folders;
 | 
				
			||||||
  QDomDocument dokument;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!skin_file.open(QIODevice::Text | QIODevice::ReadOnly) || !dokument.setContent(&skin_file, true)) {
 | 
					  base_skin_folders.append(APP_SKIN_PATH);
 | 
				
			||||||
    if (ok) {
 | 
					  base_skin_folders.append(getUserSkinBaseFolder());
 | 
				
			||||||
      *ok = false;
 | 
					
 | 
				
			||||||
 | 
					  while (!base_skin_folders.isEmpty()) {
 | 
				
			||||||
 | 
					    const QString skin_folder = base_skin_folders.takeAt(0) + QDir::separator() + skin_name + QDir::separator();
 | 
				
			||||||
 | 
					    const QString metadata_file = skin_folder + APP_SKIN_METADATA_FILE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (QFile::exists(metadata_file)) {
 | 
				
			||||||
 | 
					      QFile skin_file(metadata_file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      QDomDocument dokument;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (!skin_file.open(QIODevice::Text | QIODevice::ReadOnly) || !dokument.setContent(&skin_file, true)) {
 | 
				
			||||||
 | 
					        if (ok) {
 | 
				
			||||||
 | 
					          *ok = false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return skin;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      const QDomNode skin_node = dokument.namedItem(QSL("skin"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Obtain visible skin name.
 | 
				
			||||||
 | 
					      skin.m_visibleName = skin_name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Obtain author.
 | 
				
			||||||
 | 
					      skin.m_author = skin_node.namedItem(QSL("author")).namedItem(QSL("name")).toElement().text();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Obtain email.
 | 
				
			||||||
 | 
					      skin.m_email = skin_node.namedItem(QSL("author")).namedItem(QSL("email")).toElement().text();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Obtain version.
 | 
				
			||||||
 | 
					      skin.m_version = skin_node.attributes().namedItem(QSL("version")).toAttr().value();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Obtain other information.
 | 
				
			||||||
 | 
					      skin.m_baseName = skin_name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Free resources.
 | 
				
			||||||
 | 
					      skin_file.close();
 | 
				
			||||||
 | 
					      skin_file.deleteLater();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Here we use "/" instead of QDir::separator() because CSS2.1 url field
 | 
				
			||||||
 | 
					      // accepts '/' as path elements separator.
 | 
				
			||||||
 | 
					      //
 | 
				
			||||||
 | 
					      // "##" is placeholder for the actual path to skin file. This is needed for using
 | 
				
			||||||
 | 
					      // images within the QSS file.
 | 
				
			||||||
 | 
					      // So if one uses "##/images/border.png" in QSS then it is
 | 
				
			||||||
 | 
					      // replaced by fully absolute path and target file can
 | 
				
			||||||
 | 
					      // be safely loaded.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      skin.m_layoutMarkupWrapper = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_wrapper.html")));
 | 
				
			||||||
 | 
					      skin.m_layoutMarkupWrapper = skin.m_layoutMarkupWrapper.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      skin.m_enclosureImageMarkup = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_enclosure_image.html")));
 | 
				
			||||||
 | 
					      skin.m_enclosureImageMarkup = skin.m_enclosureImageMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      skin.m_layoutMarkup = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_single_message.html")));
 | 
				
			||||||
 | 
					      skin.m_layoutMarkup = skin.m_layoutMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      skin.m_enclosureMarkup = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_enclosure_every.html")));
 | 
				
			||||||
 | 
					      skin.m_enclosureMarkup = skin.m_enclosureMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      skin.m_rawData = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("theme.css")));
 | 
				
			||||||
 | 
					      skin.m_rawData = skin.m_rawData.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (ok != nullptr) {
 | 
				
			||||||
 | 
					        *ok = !skin.m_author.isEmpty() && !skin.m_version.isEmpty() &&
 | 
				
			||||||
 | 
					              !skin.m_baseName.isEmpty() && !skin.m_email.isEmpty() &&
 | 
				
			||||||
 | 
					              !skin.m_layoutMarkup.isEmpty();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    return skin;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const QDomNode skin_node = dokument.namedItem(QSL("skin"));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Obtain visible skin name.
 | 
					 | 
				
			||||||
  skin.m_visibleName = skin_name;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Obtain author.
 | 
					 | 
				
			||||||
  skin.m_author = skin_node.namedItem(QSL("author")).namedItem(QSL("name")).toElement().text();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Obtain email.
 | 
					 | 
				
			||||||
  skin.m_email = skin_node.namedItem(QSL("author")).namedItem(QSL("email")).toElement().text();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Obtain version.
 | 
					 | 
				
			||||||
  skin.m_version = skin_node.attributes().namedItem(QSL("version")).toAttr().value();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Obtain other information.
 | 
					 | 
				
			||||||
  skin.m_baseName = skin_name;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Free resources.
 | 
					 | 
				
			||||||
  skin_file.close();
 | 
					 | 
				
			||||||
  skin_file.deleteLater();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Here we use "/" instead of QDir::separator() because CSS2.1 url field
 | 
					 | 
				
			||||||
  // accepts '/' as path elements separator.
 | 
					 | 
				
			||||||
  //
 | 
					 | 
				
			||||||
  // "##" is placeholder for the actual path to skin file. This is needed for using
 | 
					 | 
				
			||||||
  // images within the QSS file.
 | 
					 | 
				
			||||||
  // So if one uses "##/images/border.png" in QSS then it is
 | 
					 | 
				
			||||||
  // replaced by fully absolute path and target file can
 | 
					 | 
				
			||||||
  // be safely loaded.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const QString base_folder = APP_SKIN_PATH + QDir::separator() + skin_name + QDir::separator();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  skin.m_layoutMarkupWrapper = QString::fromUtf8(IOFactory::readTextFile(base_folder + QL1S("html_wrapper.html")));
 | 
					 | 
				
			||||||
  skin.m_layoutMarkupWrapper = skin.m_layoutMarkupWrapper.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  skin.m_enclosureImageMarkup = QString::fromUtf8(IOFactory::readTextFile(base_folder + QL1S("html_enclosure_image.html")));
 | 
					 | 
				
			||||||
  skin.m_enclosureImageMarkup = skin.m_enclosureImageMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  skin.m_layoutMarkup = QString::fromUtf8(IOFactory::readTextFile(base_folder + QL1S("html_single_message.html")));
 | 
					 | 
				
			||||||
  skin.m_layoutMarkup = skin.m_layoutMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  skin.m_enclosureMarkup = QString::fromUtf8(IOFactory::readTextFile(base_folder + QL1S("html_enclosure_every.html")));
 | 
					 | 
				
			||||||
  skin.m_enclosureMarkup = skin.m_enclosureMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  skin.m_rawData = QString::fromUtf8(IOFactory::readTextFile(base_folder + QL1S("theme.css")));
 | 
					 | 
				
			||||||
  skin.m_rawData = skin.m_rawData.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (ok != nullptr) {
 | 
					 | 
				
			||||||
    *ok = !skin.m_author.isEmpty() && !skin.m_version.isEmpty() &&
 | 
					 | 
				
			||||||
          !skin.m_baseName.isEmpty() && !skin.m_email.isEmpty() &&
 | 
					 | 
				
			||||||
          !skin.m_layoutMarkup.isEmpty();
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return skin;
 | 
					  return skin;
 | 
				
			||||||
| 
						 | 
					@ -151,10 +167,14 @@ Skin SkinFactory::skinInfo(const QString &skin_name, bool *ok) const {
 | 
				
			||||||
QList<Skin> SkinFactory::installedSkins() const {
 | 
					QList<Skin> SkinFactory::installedSkins() const {
 | 
				
			||||||
  QList<Skin> skins;
 | 
					  QList<Skin> skins;
 | 
				
			||||||
  bool skin_load_ok;
 | 
					  bool skin_load_ok;
 | 
				
			||||||
  const QStringList skin_directories = QDir(APP_SKIN_PATH).entryList(QDir::Dirs |
 | 
					  QStringList skin_directories = QDir(APP_SKIN_PATH).entryList(QDir::Dirs |
 | 
				
			||||||
                                                                     QDir::NoDotAndDotDot |
 | 
					                                                               QDir::NoDotAndDotDot |
 | 
				
			||||||
                                                                     QDir::NoSymLinks |
 | 
					                                                               QDir::NoSymLinks |
 | 
				
			||||||
                                                                     QDir::Readable);
 | 
					                                                               QDir::Readable);
 | 
				
			||||||
 | 
					  skin_directories.append(QDir(getUserSkinBaseFolder()).entryList(QDir::Dirs |
 | 
				
			||||||
 | 
					                                                                  QDir::NoDotAndDotDot |
 | 
				
			||||||
 | 
					                                                                  QDir::NoSymLinks |
 | 
				
			||||||
 | 
					                                                                  QDir::Readable));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  foreach (const QString &base_directory, skin_directories) {
 | 
					  foreach (const QString &base_directory, skin_directories) {
 | 
				
			||||||
    const Skin skin_info = skinInfo(base_directory, &skin_load_ok);
 | 
					    const Skin skin_info = skinInfo(base_directory, &skin_load_ok);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -69,7 +69,10 @@ class SkinFactory : public QObject {
 | 
				
			||||||
    // Sets the desired skin as the active one if it exists.
 | 
					    // Sets the desired skin as the active one if it exists.
 | 
				
			||||||
    void setCurrentSkinName(const QString &skin_name);
 | 
					    void setCurrentSkinName(const QString &skin_name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    QString getUserSkinBaseFolder() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private:
 | 
					  private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Loads the skin from give skin_data.
 | 
					    // Loads the skin from give skin_data.
 | 
				
			||||||
    void loadSkinFromData(const Skin &skin);
 | 
					    void loadSkinFromData(const Skin &skin);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue