Import-Export-resources-for-setup-creation

From Qt Wiki
Jump to navigation Jump to search
This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine.
Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean.

Import & Export of resources for creating a setup (windows)

Introduction

For almost every finished Qt project it is wanted and in most cases also required to carry extern resources. When porting the executable to other users on other computers that usually don't have Qt installed, it is necessary to port the needed Qt libraries, too. Also, it is often necessary to include sound files, pictures, text files and other stuff to the executable. One common way is to pack all that stuff into a zip archive and hope that the target user will manage things correctly. Another, more complicated and maybe not in every case usable way would be to use the Qt resource management.

For those of you who would like to handle import/export of every kind of resource very easily, I wrote a little "ResourceManager".

Headers & Source files

The obligatory algorithms are stored in two files: 1. resourcemanager.h 2. resourcemanager.cpp

For easy creating a setup file by mouse clicking, I also wrote a user interface. This interface additionally requires the following six files: 1. mainwindow.h 2. mainwindow.cpp 3. myQDialogGetFile.h 4. myQDialogGetFile.cpp 5. myQDialogGetNewFile.h 6. myQDialogGetNewFile.cpp

Implementation

Basic usage without user interface (not advisable!)

For basic usage of the ResourceManager, you have to create a new project (this will be the executable that will import the resources to your setup) and add the two obligatory files (resourcemanager.h, resourcemanager.cpp). In the main source file, you only have to specify the resources and pass them to the resourcemanager algorithm. There are two functions that can be used, depending on how the resources shall be passed: a) as a QStringList:

QStringList listResources;
listResources << "Path/To/Resource/resource1.suffix|Path/To/Export/Resource/On/User/Computer/resource1.suffix" << "Path/To/Resource/resource2.suffix|Path/To/Export/Resource/On/User/Computer/resource2.suffix";
ResourceManager resManager("Path/To/Setup.exe");
if(!resManager.importResourcesFromList(listResources))
 resManager.displayError();
else
 QMessageBox::information(this, "ResourceManager", "Import successful!");

b) from an existing resource table file (ini format): ResourceTable.ini:

[Resources]
res_1=Path/To/Resource/resource1.suffix|Path/To/Export/Resource/On/User/Computer/resource1.suffix
res_2=Path/To/Resource/resource2.suffix|Path/To/Export/Resource/On/User/Computer/resource2.suffix
QString fileResources = "Path/To/ResourceTable.ini";
ResourceManager resManager("Path/To/Setup.exe");
if(!resManager.importResourcesFromFile(fileResources))
 resManager.displayError();
else
 QMessageBox::information(this, "ResourceManager", "Import successful!");

I strongly recommend not to call the resourcemanager algorithms manually, because there are lots of mistakes that can happen like typing a wrong resource path, using forbidden characters (e.g.g backslash) and so on. It is advisable to use the user interface instead.

Using graphical user interface

For using the interface, you only have to create a new project and import all files given above (resourcemanager.h/.cpp, mainwindow.h/.cpp, myQDialogGetFile.h/.cpp, myQDialogGetNewFile.h/.cpp), compile and run it. After the mainwindow is shown, you can select new resources from your computer and add them to the resource table, or you can load an already existing resource table (ini file). By clicking the button "import to library" you can import all files from the table to your specified setup file. You can also save the chosen resources as a new resource table file for later use.

Exporting resources on clients computer

The only thing you have to modify in your setup file project is to add the two resourcemanager files (resourcemanager.h/.cpp) and place the following command into the main function (or anywhere else at the point of execution where resources should be exported):

int main(int argc, char** args)
{
 ResourceManager resManager("Path/To/Setup.exe", ResourceManager::EXPORT);
 if(!resManager.exportResources())
 resManager.displayError();
 else
 QMessageBox::information(this, "ResourceManager", "Export successful!");

//continue execution as wanted…
}

The path you have to pass to the ResourceManager is the path of the setup file itsself, because there are the resources stored.

Files

resourcemanager.h

// Library - resourcemanager.h

#ifndef ''HEADER_RESOURCEMANAGER''
#define ''HEADER_RESOURCEMANAGER''

// —— header includes ——

#include "windows.h"
#include <QApplication>
#include <QMessageBox>
#include <QString>
#include <QTextStream>
#include <QDir>
#include <QSettings>
#include <QFile>

// —— class forward declaration ——

class ResourceManager;

// —— class declaration ——

class ResourceManager
{
 public:
 enum enumType {IMPORT, EXPORT};

private:
 enumType type;
 QString fileLibrary, idResourceTable, idResource, keyResourceTableFile, errorMessage;
 QByteArray dataResourceTableImport, dataResourceTableExport;

public:
 ResourceManager(const QString &library = "", enumType type = ResourceManager::IMPORT);
 bool setLibrary(const QString &);
 bool importResourcesFromFile(const QString &);
 bool importResourcesFromList(QStringList &);
 bool exportResources();
 void displayError();

private:
 bool createResourceTableFromFile(const QString &);
 bool createResourceTableFromList(QStringList &);
 bool importResourceTable(HANDLE);
 bool importResources(HANDLE);
 bool exportResourceTable(HANDLE);
 bool exportResources(HANDLE);
};

#endif

resourcemanager.cpp

// Library - resourcemanager.cpp

// —— header includes ——

#include "resourcemanager.h"

// —————————————————————————————————-
 // —— ResourceManager ——
 // —————————————————
 // —— constructors ——

ResourceManager::ResourceManager(const QString &library, enumType type)
 {
 this->setLibrary(library);
 this->type = type;

this->idResourceTable = "myResource_Table";
 this->idResource = "myResource_";
 this->keyResourceTableFile = "Resources/res_";
 this->dataResourceTableImport.clear();
 this->dataResourceTableExport.clear();

this->errorMessage = "No errors occured!";
 }

// —————————————————
 // —— private functions ——

bool ResourceManager::importResourceTable(HANDLE hLibrary)
 {
 if(this->type [[Image:= ResourceManager::IMPORT)
    {
      this->errorMessage = "Import access denied|]] Object is in export mode.";
 return false;
 }
 LPVOID cdataResourceTableExport = (LPVOID)this->dataResourceTableExport.data();
 if(!UpdateResource(hLibrary,
 RT_RCDATA,
 this->idResourceTable.toStdWString().c_str(),
 MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
 cdataResourceTableExport,
 this->dataResourceTableExport.length()))
 {
 this->errorMessage = "Unexpected error occured: failed to update resource table";
 return false;
 }
 return true;
 }

bool ResourceManager::importResources(HANDLE hLibrary)
 {
 QList<QByteArray> resources = this->dataResourceTableImport.split('?');
 for(int i = 0, ii = 1; i < resources.count(); i+'', ii)
 {
 QString resourceInfo = resources.at(i);
 if(!resourceInfo.contains("|"))
 {
 this->errorMessage = "Invalid resource table configuration (missing separator '|')";
 return false;
 }
 resourceInfo.replace("", "/");
 QString resourceFrom = resourceInfo.split("|").at(0),
 resourceTo = resourceInfo.split("|").at(1);
 if(resourceFrom.contains(QRegExp("[|'''?quot;<> ]")) || resourceTo.contains(QRegExp("[|'''?quot;<> ]")))
 {
 this->errorMessage = "Invalid resource table configuration (forbidden characters '|'''?quot;<>')";
 return false;
 }
 if(resourceFrom.count(":") > 1 || resourceTo.count(":") > 1)
 {
 this->errorMessage = "Invalid resource table configuration (forbidden multi occurrence of ':', only allowed for drive specification)";
 return false;
 }

 QFile file(resourceFrom);
 if(!file.exists())
 {
 this->errorMessage = "A specified resource doesn't exist: '"''resourceFrom''"'";
 return false;
 }
 QByteArray resourceData;
 if(file.open(QIODevice::ReadOnly))
 {
 resourceData = file.readAll();
 file.close();
 }
 else
 {
 this->errorMessage = "Unexpected error occured: failed to open resource: '"''resourceFrom''"'";
 return false;
 }

 QString idResource = this->idResource+QString::number(ii);
 LPVOID cResourceData = (LPVOID)(LPCTSTR)resourceData.data();
 if(!UpdateResource(hLibrary,
 RT_RCDATA,
 idResource.toStdWString().c_str(),
 MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
 cResourceData,
 resourceData.size()))
 {
 this->errorMessage = "Unexpected error occured: failed to update resource: '"''resourceFrom''"'";
 return false;
 }
 }
 return true;
 }

 bool ResourceManager::exportResourceTable(HANDLE hLibrary)
 {
 if(this->type [[Image:= ResourceManager::EXPORT)
    {
      this->errorMessage = "Export access denied|]] Object is in import mode.";
 return false;
 }
 HANDLE hResource = FindResource((HMODULE)hLibrary, this->idResourceTable.toStdWString().c_str(), RT_RCDATA);
 if (hResource != NULL)
 {
 int resourceSize = (int)SizeofResource((HMODULE)hLibrary, (HRSRC)hResource);
 HANDLE hResourceLoaded = LoadResource((HMODULE)hLibrary, (HRSRC)hResource);
 if (hResourceLoaded != NULL)
 {
 QByteArray resourceData = QByteArray::fromRawData((char''')LockResource(hResourceLoaded), resourceSize);
 if(resourceData.size() > 0)
 this->dataResourceTableExport = resourceData;
 else
 {
 this->errorMessage = "Unexpected error occured: failed to lock resource table";
 return false;
 }
 }
 else
 {
 this->errorMessage = "Unexpected error occured: failed to load resource table";
 return false;
 }
 }
 else
 {
 this->errorMessage = "Unexpected error occured: failed to locate resource table";
 return false;
 }
 return true;
 }

 bool ResourceManager::exportResources(HANDLE hLibrary)
 {
 QList<QByteArray> listResources = this->dataResourceTableExport.split('?');

 for(int i = 0; i < listResources.count(); i)
 {
 if(!listResources.at(i).contains('|'))
 {
 this->errorMessage = "Invalid resource table configuration (missing separator '|')";
 return false;
 }
 QString idResource = this->idResource+listResources.at(i).split('|').at(0),
 resourceTo = listResources.at(i).split('|').at(1);

 if(resourceTo.contains('/'))
 {
 QStringList resourceToDirs = resourceTo.split('/');
 resourceToDirs.removeLast();
 QDir directory;
 QString resourceToDir;
 for(int ii = 0; ii < resourceToDirs.count(); ii)
 {
 resourceToDir''= (ii  0) ? resourceToDirs.at(ii) : "/"+resourceToDirs.at(ii);
        }
        directory.mkpath(resourceToDir);
      }
      LPCTSTR cidResource = (LPCTSTR)idResource.toStdWString().c_str();
      HANDLE hResource = FindResource((HMODULE)hLibrary, cidResource, RT_RCDATA);
      if (hResource  NULL)
 {
 this->errorMessage = "Unexpected error occured: failed to locate resource";
 return false;
 }
 int resourceSize = (int)SizeofResource((HMODULE)hLibrary, (HRSRC)hResource);
 HANDLE hResourceLoaded = LoadResource((HMODULE)hLibrary, (HRSRC)hResource);
 if (hResourceLoaded != NULL)
 {
 QByteArray resourceData = QByteArray::fromRawData((char*)LockResource(hResourceLoaded), resourceSize);
 if(resourceData.size() > 0)
 {
 QFile file(resourceTo);
 if(file.open(QIODevice::WriteOnly))
 {
 file.write(resourceData);
 file.close();
 }
 else
 {
 this->errorMessage = "Unexpected error occured: failed to create resource file";
 return false;
 }
 }
 else
 {
 this->errorMessage = "Unexpected error occured: failed to lock resource";
 return false;
 }
 }
 else
 {
 this->errorMessage = "Unexpected error occured: failed to load resource";
 return false;
 }
 }
 return true;
 }

bool ResourceManager::createResourceTableFromFile(const QString &fileResources)
 {
 QSettings iniResources(fileResources, QSettings::IniFormat);
 QString dataResourceTableImport, dataResourceTableExport;
 for(int i = 1; iniResources.value(this->keyResourceTableFile+QString::number(i), "").toString() != ""; i++)
 {
 QString resourceInfo = iniResources.value(this->keyResourceTableFile+QString::number(i), "").toString();
 if(!resourceInfo.contains("|"))
 {
 this->errorMessage = "Invalid resource table configuration (missing separator '|')";
 return false;
 }
 resourceInfo.replace("", "/");
 QString resourceFrom = resourceInfo.split("|").at(0),
 resourceTo = resourceInfo.split("|").at(1);
 if(resourceFrom.contains(QRegExp("[|'''?quot;<> ]")) || resourceTo.contains(QRegExp("[|'''?quot;<> ]")))
 {
 this->errorMessage = "Invalid resource table configuration (forbidden characters '|*?quot;<>')";
 return false;
 }
 if(resourceFrom.count(":") > 1 || resourceTo.count(":") > 1)
 {
 this->errorMessage = "Invalid resource table configuration (forbidden multi occurrence of ':', only allowed for drive specification)";
 return false;
 }
 if(!QFile::exists(resourceFrom))
 {
 this->errorMessage = "A specified resource doesn't exist: '"''resourceFrom''"'";
 return false;
 }
 dataResourceTableImport = (i  1) ? resourceFrom+"|"+resourceTo : dataResourceTableImport+"?"+resourceFrom+"|"+resourceTo;
      dataResourceTableExport = (i  1) ? QString::number(i)+"|"''resourceTo : dataResourceTableExport''"?"''QString::number(i)''"|"''resourceTo;
 }
 this->dataResourceTableImport = dataResourceTableImport.toStdString().c_str();
 this->dataResourceTableExport = dataResourceTableExport.toStdString().c_str();
 return true;
 }

 bool ResourceManager::createResourceTableFromList(QStringList &listResources)
 {
 if(listResources.count()  0)
      return false;
    QString dataResourceTableImport, dataResourceTableExport;
    for(int i = 0, ii = 1; i < listResources.count(); i++, ii++)
    {
      QString resourceInfo = listResources.at(i);
      resourceInfo.replace("\\", "/");
      QString resourceFrom = resourceInfo.split("|").at(0), resourceTo = resourceInfo.split("|").at(1);
      if(!QFile::exists(resourceFrom))
      {
        this->errorMessage = "Non-existing resources were found.";
        return false;
      }
      if(resourceFrom.contains(QRegExp("[|*?\"<> ]")) || resourceTo.contains(QRegExp("[|*?\"<> ]")))
      {
        this->errorMessage = "Invalid resource table configuration (forbidden characters '|*?\"<>')";
        return false;
      }
      if(resourceFrom.count(":") > 1 || resourceTo.count(":") > 1)
      {
        this->errorMessage = "Invalid resource table configuration (forbidden multi occurrence of ':', only allowed for drive specification)";
       return false;
      }
      dataResourceTableImport = (ii  1) ? resourceFrom''"|"''resourceTo : dataResourceTableImport''"?"''resourceFrom''"|"''resourceTo;
 dataResourceTableExport = (ii == 1) ? QString::number(ii)''"|"''resourceTo : dataResourceTableExport''"?"''QString::number(ii)''"|"''resourceTo;
 }
 this->dataResourceTableImport = dataResourceTableImport.toStdString().c_str();
 this->dataResourceTableExport = dataResourceTableExport.toStdString().c_str();
 return true;
 }


 // —————————————————
 // —— public functions ——

 bool ResourceManager::setLibrary(const QString &library)
 {
 if(!QFile::exists(library) && library != "")
 return false;
 this->fileLibrary = library;
 return true;
 }

 bool ResourceManager::importResourcesFromFile(const QString &fileResourceTable)
 {
 if(!QFile::exists(this->fileLibrary))
 {
 this->errorMessage = "The specified library doesn't exist.";
 return false;
 }
 if(!QFile::exists(fileResourceTable))
 {
 this->errorMessage = "The specified resource table doesn't exist.";
 return false;
 }
 if(!fileResourceTable.contains(".ini"))
 {
 this->errorMessage = "The specified resource table is no valid file format ('.ini' expected).";
 return false;
 }
 this->createResourceTableFromFile(fileResourceTable);
 HANDLE hLibrary = BeginUpdateResource(this->fileLibrary.toStdWString().c_str(), FALSE);
 if(hLibrary == NULL)
 {
 this->errorMessage = "Unexpected error occured: failed to open library";
 return false;
 }
 if(!this->importResourceTable(hLibrary))
 return false;
 if(!this->importResources(hLibrary))
 return false;
 EndUpdateResource(hLibrary, false);
 return true;
 }

 bool ResourceManager::importResourcesFromList(QStringList &listResourceTable)
 {
 if(!QFile::exists(this->fileLibrary))
 {
 this->errorMessage = "The specified library doesn't exist.";
 return false;
 }
 this->createResourceTableFromList(listResourceTable);
 HANDLE hLibrary = BeginUpdateResource(this->fileLibrary.toStdWString().c_str(), FALSE);
 if(hLibrary == NULL)
 {
 this->errorMessage = "Unexpected error occured: failed to open library";
 return false;
 }
 if(!this->importResourceTable(hLibrary))
 return false;
 if(!this->importResources(hLibrary))
 return false;
 EndUpdateResource(hLibrary, false);
 return true;
 }

 bool ResourceManager::exportResources()
 {
 if(!QFile::exists(this->fileLibrary))
 {
 this->errorMessage = "The specified library doesn't exist.";
 return false;
 }
 HANDLE hLibrary = LoadLibrary(this->fileLibrary.toStdWString().c_str());
 if(hLibrary == NULL)
 {
 this->errorMessage = "Unexpected error occured: failed to open library";
 return false;
 }
 if(!this->exportResourceTable(hLibrary))
 return false;
 if(!this->exportResources(hLibrary))
 return false;
 FreeLibrary((HMODULE)hLibrary);

 return true;
 }

 void ResourceManager::displayError()
 {
 if(this->type == ResourceManager::IMPORT)
 QMessageBox::information(0, "Import failed", this->errorMessage);
 else
 QMessageBox::information(0, "Export failed", this->errorMessage);
 }

mainwindow.h

// ResourceManager - mainwindow.h

#ifndef ''HEADER_RESOURCEMANAGER_MAINWINDOW''
#define ''HEADER_RESOURCEMANAGER_MAINWINDOW''

// —— header includes ——

#include <QDebug>
#include <QApplication>
#include <QObject>
#include <QDesktopWidget>
#include <QWidget>
#include <QMessageBox>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QFileSystemModel>
#include <QFileIconProvider>
#include <QTreeView>
#include <QListWidget>
#include <QTableWidget>
#include <QHeaderView>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include "myQDialogGetFile.h"
#include "myQDialogGetNewFile.h"
#include "resourcemanager.h"


// —— class forward declaration ——

class window_main;


// —— class declaration ——

class window_main : public QWidget
{
 Q_OBJECT

 private:
 myQDialogGetFile *winGetLibrary, *winGetResourceTable;
 myQDialogGetNewFile *winGetNewResourceTable;
 QString workingDirectory, nameResourceTableFileStd;
 QHBoxLayout *layoutMain, *layoutRightTwoLibrary, *layoutRightTwoResources;
 QVBoxLayout *layoutLeft, *layoutMiddle, *layoutRightOne, *layoutRightTwo;
 QGridLayout *layoutRight;
 QFileSystemModel *filesystemmodel;
 QTreeView *treeview;
 QListWidget *listDirectories;
 QTableWidget *tableResources;
 QLabel *labelTreeview, *labelListWidget, *labelTableWidget, *labelLibrary;
 QLineEdit *editLibrary;
 QPushButton *addResources, *removeResources, *clearResources,
 *getResources, *saveResources,
 *getLibrary, *clearLibrary,
 *importAll, *exportAll;
 QDir directory;

 public:
 enum enumWidgets {TABLE_RESOURCES, EDIT_LIBRARY};

 public:
 window_main(QString, QWidget '''parent = 0);
 void showEvent(QShowEvent''');

 private:
 void updateButtonState();
 void highlightErrors(enumWidgets);
 QString adaptStringWidth(const QString &, int);

 public slots:
 void treeviewClicked(const QModelIndex &);
 void listwidgetItemDoubleClicked(QListWidgetItem ''');
 void tableResourcesRowsChanged(QModelIndex, int, int);
 void editLibraryTextChanged(const QString &);
 void buttonAddResources();
 void buttonRemoveResources();
 void buttonClearResources();
 void buttonGetResources();
 void buttonSaveResources();
 void buttonGetLibrary();
 void buttonClearLibrary();
 void buttonImportAll();
 void buttonExportAll();
};

#endif

mainwindow.cpp

// ResourceManager - mainwindow.cpp

 // —— header includes ——

 #include "mainwindow.h"


 // —————————————————————————————————-
 // —— main ——

 int main(int argc, char'''* args)
 {
 QApplication app(argc, args);
 QString filePath = args[0];

 window_main winMain(filePath);

 return app.exec();
 }


 // —————————————————————————————————-
 // —— window_main ——
 // —————————————————
 // —— constructors ——

 window_main::window_main(QString filePath, QWidget *parent) : QWidget(parent)
 {
 QStringList workingDirs = QString(filePath).split("");
 workingDirs.removeLast();
 for(int i = 0; i < workingDirs.count(); i)
 this->workingDirectory''= (i == 0) ? workingDirs.at(i) : ""''workingDirs.at(i);

 this->nameResourceTableFileStd = "ResourceTable.ini";

 this->layoutMain = new QHBoxLayout;
 this->directory = QDir(QDir::currentPath());
 this->filesystemmodel = new QFileSystemModel;
 this->filesystemmodel->setRootPath(QDir::currentPath());
 this->filesystemmodel->setFilter(QDir::Drives|QDir::AllDirs|QDir::Dirs|QDir::NoDotAndDotDot);

 this->layoutLeft = new QVBoxLayout;
 this->labelTreeview = new QLabel("Computer:");
 this->layoutLeft->addWidget(this->labelTreeview);
 this->treeview = new QTreeView;
 this->layoutLeft->addWidget(this->treeview);
 this->treeview->setModel(this->filesystemmodel);
 this->treeview->setFixedWidth(270);
 this->treeview->setHeaderHidden(true);
 for(int i = 1; i < this->filesystemmodel->columnCount(); i)
 this->treeview->hideColumn(i);
 this->treeview->resizeColumnToContents(0);
 this->treeview->header()->setStretchLastSection(false);
 this->treeview->setIndentation(20);
 this->treeview->setSortingEnabled(true);
 this->treeview->setAnimated(false);
 this->treeview->setCurrentIndex(this->filesystemmodel->index(QApplication::applicationDirPath()));
 connect(this->treeview, SIGNAL (clicked(const QModelIndex &)), this, SLOT (treeviewClicked(const QModelIndex &)));
 connect(this->treeview, SIGNAL (expanded(const QModelIndex &)), this, SLOT (treeviewClicked(const QModelIndex &)));
 this->layoutMain->addLayout(this->layoutLeft);

 this->layoutMiddle = new QVBoxLayout;
 this->labelListWidget = new QLabel;
 this->layoutMiddle->addWidget(this->labelListWidget);
 this->listDirectories = new QListWidget;
 this->layoutMiddle->addWidget(listDirectories);
 this->listDirectories->setFixedWidth(300);
 this->listDirectories->setSelectionMode(QAbstractItemView::ExtendedSelection);
 connect(this->listDirectories, SIGNAL (itemDoubleClicked(QListWidgetItem *)), this, SLOT (listwidgetItemDoubleClicked(QListWidgetItem *)));
 this->labelListWidget->setText(this->adaptStringWidth(this->filesystemmodel->filePath(this->treeview->currentIndex()), this->listDirectories->width()-10));
 this->layoutMain->addLayout(this->layoutMiddle);

 this->layoutRight = new QGridLayout;

 this->layoutRightOne = new QVBoxLayout;
 this->addResources = new QPushButton("Add >>");
 this->layoutRightOne->addWidget(this->addResources);
 connect(this->addResources, SIGNAL (clicked()), this, SLOT (buttonAddResources()));
 this->removeResources = new QPushButton("<< Remove");
 this->layoutRightOne->addWidget(this->removeResources);
 connect(this->removeResources, SIGNAL (clicked()), this, SLOT (buttonRemoveResources()));

 this->layoutRight->addLayout(this->layoutRightOne, 1, 0);
 this->labelTableWidget = new QLabel("Manual selection:");
 this->layoutRight->addWidget(this->labelTableWidget, 0, 1);
 this->tableResources = new QTableWidget;
 this->layoutRight->addWidget(this->tableResources, 1, 1);
 this->tableResources->setMinimumSize(350, 250);
 this->tableResources->setSelectionMode(QAbstractItemView::ExtendedSelection);
 this->tableResources->setRowCount(0);
 this->tableResources->setColumnCount(2);
 this->tableResources->verticalHeader()->hide();
 QStringList tableResourcesHeaderH;
 tableResourcesHeaderH << "Import path" << "Export path";
 this->tableResources->setHorizontalHeaderLabels(tableResourcesHeaderH);
 this->tableResources->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
 for(int i = 0; i < this->tableResources->rowCount(); i''+)
 this->tableResources->setRowHeight(i, 17);
 QAbstractItemModel *tableResourcesModel = this->tableResources->model();
 connect(tableResourcesModel, SIGNAL (rowsInserted(QModelIndex,int,int)), this, SLOT (tableResourcesRowsChanged(QModelIndex, int, int)));
 connect(tableResourcesModel, SIGNAL (rowsRemoved(QModelIndex,int,int)), this, SLOT (tableResourcesRowsChanged(QModelIndex, int, int)));

this->layoutRightTwo = new QVBoxLayout;
 this->layoutRightTwoResources = new QHBoxLayout;
 this->clearResources = new QPushButton("reset");
 this->layoutRightTwoResources->addWidget(this->clearResources);
 connect(this->clearResources, SIGNAL (clicked()), this, SLOT (buttonClearResources()));
 this->getResources = new QPushButton("load resources");
 this->layoutRightTwoResources->addWidget(this->getResources);
 connect(this->getResources, SIGNAL (clicked()), this, SLOT (buttonGetResources()));
 this->saveResources = new QPushButton("save resources");
 this->layoutRightTwoResources->addWidget(this->saveResources);
 connect(this->saveResources, SIGNAL (clicked()), this, SLOT (buttonSaveResources()));
 this->layoutRightTwo->addLayout(this->layoutRightTwoResources);

this->labelLibrary = new QLabel("Library:");
 this->layoutRightTwo->addWidget(this->labelLibrary);
 this->layoutRightTwoLibrary = new QHBoxLayout;
 this->editLibrary = new QLineEdit;
 this->layoutRightTwoLibrary->addWidget(this->editLibrary);
 this->editLibrary->setReadOnly(true);
 connect(this->editLibrary, SIGNAL (textChanged(const QString &)), this, SLOT (editLibraryTextChanged(const QString &)));
 this->getLibrary = new QPushButton("search");
 this->layoutRightTwoLibrary->addWidget(this->getLibrary);
 connect(this->getLibrary, SIGNAL (clicked()), this, SLOT (buttonGetLibrary()));
 this->clearLibrary = new QPushButton("reset");
 this->layoutRightTwoLibrary->addWidget(this->clearLibrary);
 connect(this->clearLibrary, SIGNAL (clicked()), this, SLOT (buttonClearLibrary()));
 this->layoutRightTwo->addLayout(this->layoutRightTwoLibrary);

this->importAll = new QPushButton("import to library");
 this->layoutRightTwo->addWidget(this->importAll);
 connect(this->importAll, SIGNAL (clicked()), this, SLOT (buttonImportAll()));
 this->exportAll = new QPushButton("export from library");
 this->layoutRightTwo->addWidget(this->exportAll);
 connect(this->exportAll, SIGNAL (clicked()), this, SLOT (buttonExportAll()));
 this->updateButtonState();

this->layoutRight->addLayout(this->layoutRightTwo, 2, 1);
 this->layoutMain->addLayout(this->layoutRight);

this->winGetResourceTable = new myQDialogGetFile(this, "Choose ResourceTable file:", "choose");
 QStringList suffixFilterResourceTable;
 suffixFilterResourceTable << "ini";
 this->winGetResourceTable->setSuffixFilter(suffixFilterResourceTable);
 this->winGetNewResourceTable = new myQDialogGetNewFile("ini", this, "ResourceManager", "Choose file destination:", "save");
 this->winGetLibrary = new myQDialogGetFile(this, "Select library:");

this->setLayout(layoutMain);
 this->setWindowTitle("ResourceManager");
 this->show();
 this->move(QApplication::desktop()->screen()->rect().center() - this->rect().center());
 }

// —————————————————
 // —— public events ——

void window_main::showEvent(QShowEvent '''event)
 {
 QWidget::showEvent(event);
 this->treeviewClicked(this->treeview->currentIndex());
 }


 // —————————————————
 // —— public slots ——

 void window_main::treeviewClicked(const QModelIndex &currentIndex)
 {
 if(!currentIndex.isValid())
 return;
 QString dirPath = this->filesystemmodel->filePath(currentIndex);
 dirPath.replace("", "/");
 this->labelListWidget->setText(this->adaptStringWidth(dirPath, this->listDirectories->width()-10));
 this->directory = QDir(dirPath);
 QStringList dirContents = directory.entryList(QDir::Files|QDir::NoDotAndDotDot, QDir::DirsFirst);
 if(this->listDirectories->count() > 0)
 this->listDirectories->clear();

 for(int i = 0; i < dirContents.count(); i+'')
 {
 QFileInfo fileInfo;
 if(dirPath.right(1) == "/")
 fileInfo.setFile(dirPath+dirContents.at(i));
 else
 fileInfo.setFile(dirPath''"/"''dirContents.at(i));

 QFileIconProvider iconProvider;
 this->listDirectories->addItem(new QListWidgetItem(iconProvider.icon(fileInfo), dirContents.at(i)));
 this->listDirectories->item(this->listDirectories->count()-1)->setFlags(Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled);
 }
 }

 void window_main::listwidgetItemDoubleClicked(QListWidgetItem '''item)
 {
 this->buttonAddResources();
 }

 void window_main::tableResourcesRowsChanged(QModelIndex, int, int)
 {
 this->updateButtonState();
 }

 void window_main::editLibraryTextChanged(const QString &pathLibrary)
 {
 this->updateButtonState();
 this->highlightErrors(window_main::EDIT_LIBRARY);
 if(!QFile::exists(pathLibrary) && pathLibrary != "")
 QMessageBox::information(this, "Warning", "The selected file does not exist!");
 }

 void window_main::buttonAddResources()
 {
 QList<QListWidgetItem'''> selectedItems = this->listDirectories->selectedItems();
 if(selectedItems.count()  0)
      return;
    int rowCountOld = this->tableResources->rowCount();
    foreach(QListWidgetItem *item, selectedItems)
    {
      QString dirPath = (this->directory.absolutePath().right(1)  "" || this->directory.absolutePath().right(1) == "/") ? this->directory.absolutePath() : this->directory.absolutePath()''"/";
 QList<QTableWidgetItem'''> itemMatches = this->tableResources->findItems(dirPath+item->text(), Qt::MatchExactly);
 if(itemMatches.count() > 0)
 continue;
 this->tableResources->setRowCount(this->tableResources->rowCount()+1);
 this->tableResources->setRowHeight(this->tableResources->rowCount()-1, 17);
 this->tableResources->setItem(this->tableResources->rowCount()-1, 0, new QTableWidgetItem);
 this->tableResources->item(this->tableResources->rowCount()-1, 0)->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
 this->tableResources->item(this->tableResources->rowCount()-1, 0)->setIcon(item->icon());
 this->tableResources->item(this->tableResources->rowCount()-1, 0)->setText(dirPath+item->text());
 this->tableResources->item(this->tableResources->rowCount()-1, 0)->setToolTip(dirPath+item->text());
 this->tableResources->setItem(this->tableResources->rowCount()-1, 1, new QTableWidgetItem);
 this->tableResources->item(this->tableResources->rowCount()-1, 1)->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEditable|Qt::ItemIsEnabled);
 this->tableResources->item(this->tableResources->rowCount()-1, 1)->setIcon(item->icon());
 this->tableResources->item(this->tableResources->rowCount()-1, 1)->setText("exportPath/"+item->text());
 this->tableResources->item(this->tableResources->rowCount()-1, 1)->setToolTip("Click to edit export path…");
 }
 if(this->tableResources->rowCount() != rowCountOld)
 this->labelTableWidget->setText("Manual selection:");
 this->highlightErrors(window_main::TABLE_RESOURCES);
 }

void window_main::buttonRemoveResources()
 {
 QList<QTableWidgetItem*> selectedTableItems = this->tableResources->selectedItems();
 if(selectedTableItems.count() == 0)
 return;
 int rowCountOld = this->tableResources->rowCount();
 foreach(QTableWidgetItem* item, selectedTableItems)
 this->tableResources->removeRow(item->row());
 if(this->tableResources->rowCount() != rowCountOld)
 this->labelTableWidget->setText("Manual selection:");
 this->highlightErrors(window_main::TABLE_RESOURCES);
 }

void window_main::buttonClearResources()
 {
 while(this->tableResources->rowCount() > 0)
 this->tableResources->removeRow(0);
 this->labelTableWidget->setText("Manual selection:");
 }

void window_main::buttonGetResources()
 {
 this->winGetResourceTable->exec();
 if(!this->winGetResourceTable->isExecuted())
 return;
 QString winData = this->winGetResourceTable->getData();

if(QFileInfo(winData).suffix() != "ini")
 {
 QMessageBox::information(this, "Error", "The chosen file is no valid ResourceTable file format.file format: '.ini'");
 return;
 }
 this->buttonClearResources();

this->labelTableWidget->setText(this->adaptStringWidth(winData, this->tableResources->width()-10));

 QSettings iniFile(winData, QSettings::IniFormat);
 for(int i = 0; iniFile.value("Resources/res_"''QString::number(i+1), "").toString() != ""; i''+)
 {
 QStringList resourceInfo = iniFile.value("Resources/res_"+QString::number(i+1), "").toString().split("|");
 QFileInfo fileInfo;
 QFileIconProvider iconProvider;
 if(QFile::exists(resourceInfo.at(0)))
 fileInfo.setFile(resourceInfo.at(0));

 this->tableResources->setRowCount(this->tableResources->rowCount()''1);
 this->tableResources->setRowHeight(this->tableResources->rowCount()-1, 17);
 this->tableResources->setItem(this->tableResources->rowCount()-1, 0, new QTableWidgetItem);
 this->tableResources->item(this->tableResources->rowCount()-1, 0)->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEnabled);
 if(QFile::exists(resourceInfo.at(0)))
 this->tableResources->item(this->tableResources->rowCount()-1, 0)->setIcon(iconProvider.icon(fileInfo));
 this->tableResources->item(this->tableResources->rowCount()-1, 0)->setText(resourceInfo.at(0));
 this->tableResources->setItem(this->tableResources->rowCount()-1, 1, new QTableWidgetItem);
 this->tableResources->item(this->tableResources->rowCount()-1, 1)->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEditable|Qt::ItemIsEnabled);
 if(QFile::exists(resourceInfo.at(0)))
 this->tableResources->item(this->tableResources->rowCount()-1, 1)->setIcon(iconProvider.icon(fileInfo));
 this->tableResources->item(this->tableResources->rowCount()-1, 1)->setText(resourceInfo.at(1));
 this->tableResources->item(this->tableResources->rowCount()-1, 1)->setToolTip("Click to edit export path…");
 }
 this->highlightErrors(window_main::TABLE_RESOURCES);
 }

 void window_main::buttonSaveResources()
 {
 if(this->tableResources->rowCount() == 0)
 return;
 this->highlightErrors(window_main::TABLE_RESOURCES);
 this->winGetNewResourceTable->exec();
 if(!this->winGetNewResourceTable->isExecuted())
 return;
 QString winData = this->winGetNewResourceTable->getData();

 QSettings iniFile(winData, QSettings::IniFormat);
 QStringList resourceEntries;
 bool success = true;
 for(int i = 0; i < this->tableResources->rowCount(); i''+)
 {
 if(!QFile::exists(this->tableResources->item(i, 0)->text()))
 {
 success = false;
 break;
 }
 QString resourceEntry = this->tableResources->item(i, 0)->text()+"|"''this->tableResources->item(i, 1)->text();
 resourceEntry.replace("", "/");
 if(resourceEntry.split("|").at(1).contains(QRegExp("[|'''?quot;<> ]")))
 {
 int ret = QMessageBox::information(this, "ResourceManager", "Error occurred in resource: '"''resourceEntry.split("|").at(1)''"'contains illegal characters: '|'''?quot;<> 'them may result in errors.resource?", QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
 if(ret == QMessageBox::No)
 continue;
 }
 resourceEntries << resourceEntry;
 iniFile.setValue("Resources/res_"''QString::number(i+1), resourceEntry);
 }
 if(!success)
 {
 QFile::remove(winData);
 QMessageBox::information(this, "ResourceManager", "Some resources have not been added to the resource file…");
 }
 else
 QMessageBox::information(this, "ResourceManager", "ResourceTable file successfully created!");
 }

 void window_main::buttonGetLibrary()
 {
 this->winGetLibrary->exec();
 if(this->winGetLibrary->getData().count() > 0)
 this->editLibrary->setText(this->winGetLibrary->getData());
 }

 void window_main::buttonClearLibrary()
 {
 this->editLibrary->setText("");
 }

 void window_main::buttonImportAll()
 {
 this->highlightErrors(window_main::TABLE_RESOURCES);
 this->highlightErrors(window_main::EDIT_LIBRARY);

 if(this->tableResources->rowCount()  0)
      return;
    QStringList listResources;
    for(int i = 0; i < this->tableResources->rowCount(); i++)
    {
      QTableWidgetItem *itemFrom = this->tableResources->item(i, 0),
                       *itemTo = this->tableResources->item(i, 1);
      if(!QFile::exists(itemFrom->text()))
      {
        QMessageBox::information(this, "Warning", "Some resources don't exist or have been deleted!");
        return;
      }
        listResources << itemFrom->text()+"|"+itemTo->text();
    }
    if(this->editLibrary->text().count()  0)
 {
 QMessageBox::information(this, "Warning", "No library selected!");
 return;
 }
 else if(!QFile::exists(this->editLibrary->text()))
 {
 QMessageBox::information(this, "Warning", "The selected library does not exist!");
 return;
 }
 ResourceManager resManager(this->editLibrary->text());
 if(!resManager.importResourcesFromList(listResources))
 resManager.displayError();
 else
 QMessageBox::information(this, "ResourceManager", "Import successful!");
 }

 void window_main::buttonExportAll()
 {
 this->highlightErrors(window_main::EDIT_LIBRARY);
 if(this->editLibrary->text().count() == 0)
 {
 QMessageBox::information(this, "Warning", "No library selected!");
 return;
 }
 else if(!QFile::exists(this->editLibrary->text()))
 {
 QMessageBox::information(this, "Warning", "The selected library does not exist!");
 return;
 }
 ResourceManager resManager(this->editLibrary->text(), ResourceManager::EXPORT);
 if(!resManager.exportResources())
 resManager.displayError();
 else
 QMessageBox::information(this, "ResourceManager", "Export successful!");
 }


 // —————————————————
 // —— private functions ——

 void window_main::updateButtonState()
 {
 if(this->editLibrary->text().count()  0 || !QFile::exists(this->editLibrary->text()))
    {
      this->clearLibrary->setDisabled(true);
      this->importAll->setDisabled(true);
      this->exportAll->setDisabled(true);
    }
    else
    {
      this->clearLibrary->setEnabled(true);
      if(this->tableResources->rowCount() > 0)
        this->importAll->setEnabled(true);
      this->exportAll->setEnabled(true);
    }
    if(this->tableResources->rowCount()  0)
 {
 this->clearResources->setDisabled(true);
 this->saveResources->setDisabled(true);
 }
 else
 {
 this->clearResources->setEnabled(true);
 this->saveResources->setEnabled(true);
 }
 }

 void window_main::highlightErrors(enumWidgets widget)
 {
 if(widget  window_main::TABLE_RESOURCES)
    {
      for(int i = 0; i < this->tableResources->rowCount(); i++)
      {
        QTableWidgetItem *itemFrom = this->tableResources->item(i, 0),
                         *itemTo = this->tableResources->item(i, 1);
        if(!QFile::exists(itemFrom->text()))
        {
          itemFrom->setBackgroundColor(QColor(255,228,225));
          itemTo->setBackgroundColor(QColor(255,228,225));
        }
        else
        {
          itemFrom->setBackgroundColor(QColor(255,255,255));
          itemTo->setBackgroundColor(QColor(255,255,255));
        }
      }
    }
    else if(widget  window_main::EDIT_LIBRARY)
 {
 QPalette palette;
 if(!QFile::exists(this->editLibrary->text()) && this->editLibrary->text().count() > 0)
 palette.setColor(this->editLibrary->backgroundRole(), QColor(255,228,225));
 else
 palette.setColor(this->editLibrary->backgroundRole(), QColor(255,255,255));
 this->editLibrary->setPalette(palette);
 }
 }

 QString window_main::adaptStringWidth(const QString &stringOld, int width)
 {
 if(QLabel(stringOld).fontMetrics().boundingRect(stringOld).width() <= width)
 return stringOld;
 QString stringNew = "";
 for(int i = 0; i < stringOld.count(); i)
 {
 stringNew''= stringOld.at(i);
 if(QLabel(stringNew).fontMetrics().boundingRect(stringNew).width()''QLabel("…").fontMetrics().boundingRect("…").width() >= width)
 break;
 }
 return stringNew''"…";
 }

myQDialogGetFile.h

// Library- myQDialogGetFile.h

#ifndef ''HEADER_MYQDIALOGGETFILE''
#define ''HEADER_MYQDIALOGGETFILE''

// —— header includes ——

#include <QApplication>
#include <QDebug>
#include <QWidget>
#include <QMessageBox>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QFileSystemModel>
#include <QFileIconProvider>
#include <QLabel>
#include <QTreeView>
#include <QListWidget>
#include <QTableWidget>
#include <QHeaderView>
#include <QLineEdit>
#include <QPushButton>


// —— class forward declaration ——

class myQDialogGetFile;


// —— class declaration ——

class myQDialogGetFile : public QDialog
{
 Q_OBJECT

 private:
 QVBoxLayout *layoutMain, *layoutLeft, *layoutRight;
 QHBoxLayout *layoutTop, '''layoutBottom;
 QFileSystemModel''' filesystemmodel;
 QLabel *labelTreeview, '''labelListWidget;
 QTreeView''' treeview;
 QListWidget* listwidget;
 QString currentDirPath, filePath;
 QStringList suffixFilter;
 QLineEdit* edit;
 QPushButton* button;
 bool execution;

 public:
 myQDialogGetFile(QWidget '''parent = 0, const QString &windowTitle = "Choose file:", const QString &buttonText = "choose");
 void showEvent(QShowEvent''');
 void closeEvent(QCloseEvent*);
 void setButtonText(const QString &);
 void setSuffixFilter(const QStringList &);
 bool isExecuted();
 QString getData();

 private:
 QString adaptStringWidth(const QString &, int);

 public slots:
 void treeviewClicked(const QModelIndex &);
 void treeviewExpanded(const QModelIndex &);
 void listwidgetitemClicked(QListWidgetItem*);
 void listwidgetitemDoubleClicked(QListWidgetItem*);
 void editTextChanged(QString);
 void buttonClicked();
};

#endif

myQDialogGetFile.cpp

// Library - myQDialogGetFile.cpp

 // —— header includes ——

 #include "myQDialogGetFile.h"


 // —————————————————————————————————-
 // —— myQDialogGetFile ——
 // —————————————————
 // —— constructors ——

 myQDialogGetFile::myQDialogGetFile(QWidget *parent, const QString &windowTitle, const QString &buttonText) : QDialog(parent)
 {
 this->currentDirPath = QApplication::applicationDirPath().replace("", "/");
 this->filePath = "";
 this->suffixFilter.clear();

 this->layoutMain = new QVBoxLayout;
 this->layoutTop = new QHBoxLayout;
 this->filesystemmodel = new QFileSystemModel;
 this->filesystemmodel->setRootPath(QDir::rootPath());
 this->filesystemmodel->setFilter(QDir::Drives|QDir::AllDirs|QDir::Dirs|QDir::NoDotAndDotDot);

 this->layoutLeft = new QVBoxLayout;
 this->labelTreeview = new QLabel("Computer:");
 this->layoutLeft->addWidget(this->labelTreeview);
 this->treeview = new QTreeView;
 this->layoutLeft->addWidget(this->treeview);
 this->treeview->setFixedWidth(270);
 this->treeview->setMinimumHeight(320);
 this->treeview->setModel(this->filesystemmodel);
 this->treeview->setHeaderHidden(true);
 for(int i = 1; i < this->filesystemmodel->columnCount(); i)
 this->treeview->hideColumn(i);
 this->treeview->resizeColumnToContents(0);
 this->treeview->header()->setStretchLastSection(false);
 this->treeview->setIndentation(20);
 this->treeview->setSortingEnabled(true);
 this->treeview->setAnimated(false);
 connect(this->treeview, SIGNAL (clicked(const QModelIndex &)), this, SLOT (treeviewClicked(const QModelIndex &)));
 connect(this->treeview, SIGNAL (expanded(const QModelIndex &)), this, SLOT (treeviewExpanded(const QModelIndex &)));
 this->layoutTop->addLayout(this->layoutLeft);

 this->layoutRight = new QVBoxLayout;
 this->labelListWidget = new QLabel;
 this->layoutRight->addWidget(this->labelListWidget);
 this->listwidget = new QListWidget;
 this->layoutRight->addWidget(listwidget);
 this->listwidget->setMinimumWidth(300);
 this->listwidget->setSelectionMode(QAbstractItemView::ExtendedSelection);
 connect(this->listwidget, SIGNAL (itemClicked(QListWidgetItem *)), this, SLOT (listwidgetitemClicked(QListWidgetItem *)));
 connect(this->listwidget, SIGNAL (itemDoubleClicked(QListWidgetItem *)), this, SLOT (listwidgetitemDoubleClicked(QListWidgetItem *)));
 this->layoutTop->addLayout(this->layoutRight);

 this->layoutBottom = new QHBoxLayout;
 this->edit = new QLineEdit;
 this->edit->setReadOnly(true);
 connect(this->edit, SIGNAL (textChanged(QString)), this, SLOT (editTextChanged(QString)));
 this->layoutBottom->addWidget(this->edit);
 this->button = new QPushButton(buttonText);
 this->layoutBottom->addWidget(this->button);
 connect(this->button, SIGNAL (clicked()), this, SLOT (buttonClicked()));
 this->layoutMain->addLayout(this->layoutTop);
 this->layoutMain->addLayout(this->layoutBottom);

 this->setLayout(layoutMain);
 this->setWindowTitle(windowTitle);
 }


 // —————————————————
 // —— public events ——

 void myQDialogGetFile::showEvent(QShowEvent *event)
 {
 QDialog::showEvent(event);
 this->treeview->setCurrentIndex(this->filesystemmodel->index(this->currentDirPath));
 this->treeviewClicked(this->treeview->currentIndex());
 this->labelListWidget->setText(this->adaptStringWidth(this->currentDirPath, this->listwidget->width()-10));
 this->edit->setText(this->filePath);
 this->execution = false;
 }

 void myQDialogGetFile::closeEvent(QCloseEvent *event)
 {
 this->currentDirPath = this->filesystemmodel->filePath(this->treeview->currentIndex());
 QDialog::closeEvent(event);
 }


 // —————————————————
 // —— public slots ——

 void myQDialogGetFile::treeviewClicked(const QModelIndex &currentIndex)
 {
 if(!currentIndex.isValid())
 return;
 QString dirPath = this->filesystemmodel->filePath(currentIndex);
 dirPath.replace("", "/");
 this->currentDirPath = dirPath;
 this->labelListWidget->setText(this->adaptStringWidth(this->currentDirPath, this->listwidget->width()-10));

 QDir directory = QDir(dirPath);
 if(this->suffixFilter.count() > 0)
 directory.setNameFilters(this->suffixFilter);
 QStringList dirContents = directory.entryList(QDir::Files|QDir::NoDotAndDotDot, QDir::DirsFirst);
 if(this->listwidget->count() > 0)
 this->listwidget->clear();

 for(int i = 0; i < dirContents.count(); i)
 {
 QFileInfo fileInfo;
 if(dirPath.right(1) == "/")
 fileInfo.setFile(dirPath+dirContents.at(i));
 else
 fileInfo.setFile(dirPath''"/"''dirContents.at(i));

 QFileIconProvider iconProvider;
 this->listwidget->addItem(new QListWidgetItem(iconProvider.icon(fileInfo), dirContents.at(i)));
 this->listwidget->item(this->listwidget->count()-1)->setFlags(Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled);
 }
 }

 void myQDialogGetFile::treeviewExpanded(const QModelIndex &currentIndex)
 {
 if(!currentIndex.isValid())
 return;
 QString dirPath = this->filesystemmodel->filePath(currentIndex);
 dirPath.replace("", "/");
 this->currentDirPath = dirPath;
 this->labelListWidget->setText(this->adaptStringWidth(this->currentDirPath, this->listwidget->width()-10));

 QDir directory = QDir(dirPath);
 if(this->suffixFilter.count() > 0)
 directory.setNameFilters(this->suffixFilter);
 QStringList dirContents = directory.entryList(QDir::Files|QDir::NoDotAndDotDot, QDir::DirsFirst);
 if(this->listwidget->count() > 0)
 this->listwidget->clear();

 for(int i = 0; i < dirContents.count(); i)
 {
 QFileInfo fileInfo;
 if(dirPath.right(1) == "/")
 fileInfo.setFile(dirPath+dirContents.at(i));
 else
 fileInfo.setFile(dirPath''"/"''dirContents.at(i));

 QFileIconProvider iconProvider;
 this->listwidget->addItem(new QListWidgetItem(iconProvider.icon(fileInfo), dirContents.at(i)));
 this->listwidget->item(this->listwidget->count()-1)->setFlags(Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled);
 }
 }

 void myQDialogGetFile::listwidgetitemClicked(QListWidgetItem *currentItem)
 {
 if(this->currentDirPath.right(1) == "/")
 this->edit->setText(this->currentDirPath+currentItem->text());
 else
 this->edit->setText(this->currentDirPath''"/"+currentItem->text());
 }

void myQDialogGetFile::listwidgetitemDoubleClicked(QListWidgetItem '''currentItem)
 {
 this->listwidgetitemClicked(currentItem);
 this->buttonClicked();
 }

 void myQDialogGetFile::editTextChanged(QString)
 {
 QString filePath = this->edit->text();
 filePath.replace("", "/");
 this->filePath = filePath;
 }

 void myQDialogGetFile::buttonClicked()
 {
 QString filePath = this->filePath;
 filePath.replace("", "/");
 if(filePath.contains(QRegExp("[|'''?quot;<> ]")))
 {
 QMessageBox::information(this, "Error", "The specified file path contains illegal characters: '|'''?/quot;<> '");
 return;
 }
 if(filePath.count(":") > 1)
 {
 QMessageBox::information(this, "Error", "Multiple occurence of charachter ':'");
 return;
 }
 if(!QFile::exists(filePath))
 {
 QMessageBox::information(this, "Error", "The specified file path doesn't exist or has been deleted.");
 return;
 }
 if(filePath.count() == 0)
 {
 QMessageBox::information(this, "Error", "No file selected.");
 return;
 }
 this->execution = true;
 this->close();
 }


 // —————————————————
 // —— private functions ——

 QString myQDialogGetFile::adaptStringWidth(const QString &stringOld, int width)
 {
 if(QLabel(stringOld).fontMetrics().boundingRect(stringOld).width() <= width)
 return stringOld;
 QString stringNew = "";
 for(int i = 0; i < stringOld.count(); i+'')
 {
 stringNew''= stringOld.at(i);
 if(QLabel(stringNew).fontMetrics().boundingRect(stringNew).width()''QLabel("…").fontMetrics().boundingRect("…").width() >= width)
 break;
 }
 return stringNew''"…";
 }


 // —————————————————
 // —— public functions ——

 void myQDialogGetFile::setButtonText(const QString &buttonText)
 {
 this->button->setText(buttonText);
 }

 void myQDialogGetFile::setSuffixFilter(const QStringList &suffixFilter)
 {
 this->suffixFilter.clear();
 foreach(QString suffix, suffixFilter)
 {
 suffix.replace(QRegExp("['''. ]"), "");
 this->suffixFilter << "*."''suffix;
 }
 }

 bool myQDialogGetFile::isExecuted()
 {
 return this->execution;
 }

 QString myQDialogGetFile::getData()
 {
 if(!this->execution)
 return "";
 return this->filePath;
 }

myQDialogGetNewFile.h

// Library - myQDialogGetNewFile.h

#ifndef ''HEADER_MYQDIALOGGETNEWFILE''
#define ''HEADER_MYQDIALOGGETNEWFILE''

// —— header includes ——

#include <QApplication>
#include <QDebug>
#include <QWidget>
#include <QMessageBox>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QFileSystemModel>
#include <QFileIconProvider>
#include <QLabel>
#include <QTreeView>
#include <QListWidget>
#include <QTableWidget>
#include <QHeaderView>
#include <QLineEdit>
#include <QPushButton>


// —— class forward declaration ——

class myQDialogGetNewFile;


// —— class declaration ——

class myQDialogGetNewFile : public QDialog
{
 Q_OBJECT

 private:
 QVBoxLayout* layoutMain;
 QHBoxLayout* layoutBottom;
 QFileSystemModel* filesystemmodel;
 QLabel *labelTreeview, '''labelEdit;
 QTreeView''' treeview;
 QString currentDirPath, filePath, fileName, fileSuffix;
 QByteArray* fileData;
 QLineEdit* edit;
 QPushButton* button;
 bool execution;

 public:
 myQDialogGetNewFile(const QString &fileSuffix, QWidget* parent = 0, const QString &fileName = "untitled", const QString &windowTitle = "Choose file destination:", const QString &buttonText = "choose");
 void showEvent(QShowEvent*);
 void closeEvent(QCloseEvent*);
 void setFileSuffix(const QString &);
 void setFileName(const QString &);
 void setButtonText(const QString &);
 bool isExecuted();
 QString getData();

 private:
 QString adaptStringWidth(const QString &, int);

 public slots:
 void treeviewClicked(const QModelIndex &);
 void treeviewExpanded(const QModelIndex &);
 void editTextChanged(QString);
 void buttonClicked();
};

#endif

myQDialogGetNewFile.cpp

// Library - myQDialogGetNewFile.cpp

 // —— header includes ——

 #include "myQDialogGetNewFile.h"


 // —————————————————————————————————-
 // —— myQDialogGetNewFile ——
 // —————————————————
 // —— constructors ——

 myQDialogGetNewFile::myQDialogGetNewFile(const QString &fileSuffix, QWidget *parent, const QString &fileName, const QString &windowTitle, const QString &buttonText) : QDialog(parent)
 {
 this->currentDirPath = QApplication::applicationDirPath().replace("", "/");
 this->fileName = fileName;
 this->fileSuffix = fileSuffix;
 this->filePath = (this->currentDirPath.right(1) == "/") ? this->currentDirPath+this->fileName''"."''this->fileSuffix : this->currentDirPath''"/"''this->fileName''"."''this->fileSuffix;

 this->layoutMain = new QVBoxLayout;
 this->filesystemmodel = new QFileSystemModel;
 this->filesystemmodel->setRootPath(QDir::rootPath());
 this->filesystemmodel->setFilter(QDir::Drives|QDir::AllDirs|QDir::Dirs|QDir::NoDotAndDotDot);

 this->labelTreeview = new QLabel;
 this->layoutMain->addWidget(this->labelTreeview);
 this->treeview = new QTreeView;
 this->layoutMain->addWidget(this->treeview);
 this->treeview->setMinimumSize(270,320);
 this->treeview->setModel(this->filesystemmodel);
 this->treeview->setHeaderHidden(true);
 for(int i = 1; i < this->filesystemmodel->columnCount(); i''+)
 this->treeview->hideColumn(i);
 this->treeview->resizeColumnToContents(0);
 this->treeview->header()->setStretchLastSection(false);
 this->treeview->setIndentation(20);
 this->treeview->setSortingEnabled(true);
 this->treeview->setAnimated(false);
 connect(this->treeview, SIGNAL (clicked(const QModelIndex &)), this, SLOT (treeviewClicked(const QModelIndex &)));
 connect(this->treeview, SIGNAL (expanded(const QModelIndex &)), this, SLOT (treeviewExpanded(const QModelIndex &)));

this->layoutBottom = new QHBoxLayout;
 this->edit = new QLineEdit;
 this->edit->setText(this->fileName);
 connect(this->edit, SIGNAL (textChanged(QString)), this, SLOT (editTextChanged(QString)));
 this->layoutBottom->addWidget(this->edit);
 this->labelEdit = new QLabel;
 this->layoutBottom->addWidget(this->labelEdit);
 this->labelEdit->setText("."''this->fileSuffix);
 this->button = new QPushButton(buttonText);
 this->layoutBottom->addWidget(this->button);
 connect(this->button, SIGNAL (clicked()), this, SLOT (buttonClicked()));
 this->layoutMain->addLayout(this->layoutBottom);

 this->setLayout(layoutMain);
 this->setWindowTitle(windowTitle);
 }


 // —————————————————
 // —— public events ——

 void myQDialogGetNewFile::showEvent(QShowEvent *event)
 {
 QDialog::showEvent(event);
 this->labelTreeview->setText(this->adaptStringWidth(this->currentDirPath, this->treeview->width()-10));
 this->treeview->setCurrentIndex(this->filesystemmodel->index(this->currentDirPath));
 this->treeviewClicked(this->treeview->currentIndex());
 this->edit->setText(this->fileName);
 this->execution = false;
 }

 void myQDialogGetNewFile::closeEvent(QCloseEvent *event)
 {
 this->currentDirPath = this->filesystemmodel->filePath(this->treeview->currentIndex());
 QDialog::closeEvent(event);
 }


 // —————————————————
 // —— public slots ——

 void myQDialogGetNewFile::treeviewClicked(const QModelIndex &currentIndex)
 {
 if(!currentIndex.isValid())
 return;
 QString dirPath = this->filesystemmodel->filePath(currentIndex);
 dirPath.replace("", "/");
 this->currentDirPath = dirPath;
 this->labelTreeview->setText(this->adaptStringWidth(this->currentDirPath, this->treeview->width()-10));
 this->filePath = (this->currentDirPath.right(1) == "/") ? this->currentDirPath+this->fileName''"."''this->fileSuffix : this->currentDirPath''"/"''this->fileName''"."''this->fileSuffix;
 }

 void myQDialogGetNewFile::treeviewExpanded(const QModelIndex &currentIndex)
 {
 if(!currentIndex.isValid())
 return;
 QString dirPath = this->filesystemmodel->filePath(currentIndex);
 dirPath.replace("", "/");
 this->currentDirPath = dirPath;
 this->labelTreeview->setText(this->adaptStringWidth(this->currentDirPath, this->treeview->width()-10));
 this->filePath = (this->currentDirPath.right(1) == "/") ? this->currentDirPath+this->fileName''"."''this->fileSuffix : this->currentDirPath''"/"''this->fileName''"."''this->fileSuffix;
 }

 void myQDialogGetNewFile::editTextChanged(QString)
 {
 QString fileName = this->edit->text();
 fileName.replace("", "/");
 this->fileName = fileName;
 this->filePath = (this->currentDirPath.right(1) == "/") ? this->currentDirPath+this->fileName''"."''this->fileSuffix : this->currentDirPath''"/"''this->fileName''"."''this->fileSuffix;
 }

 void myQDialogGetNewFile::buttonClicked()
 {
 QString dirPath = this->currentDirPath, fileName = this->fileName, filePath = this->filePath;
 dirPath.replace("", "/");
 fileName.replace("", "/");
 filePath.replace("", "/");
 if(dirPath.contains(QRegExp("[|'''?quot;<> ]")))
 {
 QMessageBox::information(this, "Error", "The specified file path contains illegal characters: '|'''?/quot;<> '");
 return;
 }
 if(dirPath.count(":") > 1)
 {
 QMessageBox::information(this, "Error", "Multiple occurence of charachter ':'");
 return;
 }
 if(!QFile::exists(dirPath))
 {
 QMessageBox::information(this, "Error", "The specified file path doesn't exist or has been deleted.");
 return;
 }

 if(fileName.contains(QRegExp("[|'''?/quot;<>: ]")))
 {
 QMessageBox::information(this, "Error", "The specified file name contains illegal characters: '|'''?/quot;<>: '");
 return;
 }
 if(fileName.count() == 0)
 {
 QMessageBox::information(this, "Error", "Please type a valid file name.");
 return;
 }

 if(QFile::exists(filePath))
 {
 if(QMessageBox::information(this, "Warning", "The specified file already exists.existing file?", QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::No)
 return;
 }
 this->execution = true;
 this->close();
 }


 // —————————————————
 // —— private functions ——

 QString myQDialogGetNewFile::adaptStringWidth(const QString &stringOld, int width)
 {
 if(QLabel(stringOld).fontMetrics().boundingRect(stringOld).width() <= width)
 return stringOld;
 QString stringNew = "";
 for(int i = 0; i < stringOld.count(); i)
 {
 stringNew''= stringOld.at(i);
 if(QLabel(stringNew).fontMetrics().boundingRect(stringNew).width()''QLabel("…").fontMetrics().boundingRect("…").width() >= width)
 break;
 }
 return stringNew''"…";
 }

// —————————————————
 // —— public functions ——

void myQDialogGetNewFile::setFileSuffix(const QString &fileSuffix)
 {
 this->fileSuffix = fileSuffix;
 }

void myQDialogGetNewFile::setFileName(const QString &fileName)
 {
 this->fileName = fileName;
 }

void myQDialogGetNewFile::setButtonText(const QString &buttonText)
 {
 this->button->setText(buttonText);
 }

bool myQDialogGetNewFile::isExecuted()
 {
 return this->execution;
 }

QString myQDialogGetNewFile::getData()
 {
 if(!this->execution)
 return "";
 return this->filePath;
 }

Feedback

I would really appreciate it to get some feedback from you, so I can improve my own skills and make the algorithms better.