diff --git a/.gitignore b/.gitignore index f147edf..fab7372 100644 --- a/.gitignore +++ b/.gitignore @@ -1,52 +1,73 @@ -# C++ objects and libs -*.slo -*.lo -*.o +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave *.a -*.la -*.lai +*.core +*.moc +*.o +*.obj +*.orig +*.rej *.so *.so.* -*.dll -*.dylib - -# Qt-es -object_script.*.Release -object_script.*.Debug -*_plugin_import.cpp +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc /.qmake.cache /.qmake.stash -*.pro.user -*.pro.user.* -*.qbs.user -*.qbs.user.* -*.moc -moc_*.cpp -moc_*.h -qrc_*.cpp -ui_*.h -*.qmlc -*.jsc -Makefile* -*build-* -*.qm -*.prl -# Qt unit tests -target_wrapper.* +# qtcreator generated files +*.pro.user* -# QtCreator -*.autosave +# xemacs temporary files +*.flc -# QtCreator Qml -*.qmlproject.user -*.qmlproject.user.* +# Vim temporary files +.*.swp -# QtCreator CMake -CMakeLists.txt.user* +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* -# QtCreator 4.8< compilation database -compile_commands.json +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe -# QtCreator local machine specific files for imported projects -*creator.user* diff --git a/cdatabase.cpp b/cdatabase.cpp new file mode 100644 index 0000000..4143ebe --- /dev/null +++ b/cdatabase.cpp @@ -0,0 +1,181 @@ +#include "common.h" +#include "cdatabase.h" + +#include + +#include + + +cDatabase::cDatabase() +{ + QSettings settings; + + m_databaseType = settings.value("database/databasetype", "").toString(); + m_hostName = settings.value("database/hostname", "").toString(); + m_port = settings.value("database/port", "").toInt(); + m_databaseName = settings.value("database/databaseName").toString(); + m_userName = settings.value("database/username", "").toString(); + m_password = settings.value("database/password").toString(); + + addTranslate("AUTOINCREMENT", "QMYSQL", "AUTO_INCREMENT"); + addTranslate("AUTOINCREMENT", "QSQLITE", "AUTOINCREMENT"); +} + +cDatabase::~cDatabase() +{ + if(m_db.isOpen()) + m_db.close(); +} + +void cDatabase::addTranslate(const QString& sql, const QString& dbType, const QString& translated) +{ + SQLTRANSLATE st = { sql, dbType, translated }; + m_sqlTranslate.append(st); +} + +QString cDatabase::translate(const QString& sql, const QString& dbType) +{ + for(QList::iterator st = m_sqlTranslate.begin();st != m_sqlTranslate.end();st++) + { + if(st->sql == sql && st->dbType == dbType) + return(st->translated); + } + return(sql); +} + +bool cDatabase::connect() +{ + m_db = QSqlDatabase::addDatabase(m_databaseType); + m_db.setHostName(m_hostName); + m_db.setPort(m_port); + m_db.setDatabaseName(m_databaseName); + m_db.setUserName(m_userName); + m_db.setPassword(m_password); + + if(!m_db.open()) + { + myDebug << m_db.lastError().text(); + return(false); + } + + if(!checkDB()) + { + myDebug << m_db.lastError().text(); + return(false); + } + + return(true); +} + +QSqlDatabase cDatabase::db() +{ + return(m_db); +} + +bool cDatabase::checkDB() +{ + QSqlQuery query(m_db); + if(!query.exec("SELECT version FROM config;")) + { + if(!createTables()) + return(false); + + if(!query.exec("SELECT version FROM config;")) + return(false); + } + + query.first(); + QString version = query.value("version").toString(); + if(version.compare(APP_VERSION)) + { + if(!upgradeDB(APP_VERSION)) + return(false); + } + + return(true); +} + +bool cDatabase::createTables() +{ + QSqlQuery query(m_db); + + // CONFIG + if(!query.exec("CREATE TABLE config " + "( version VARCHAR(32) NOT NULL " + ");")) + { + myDebug << query.lastError().text(); + return(false); + } + + if(!query.exec(QString("INSERT INTO config (version) VALUES ('%1');").arg(APP_VERSION))) + { + myDebug << query.lastError().text(); + return(false); + } + + // MANUFACTURER + if(!query.exec(QString("CREATE TABLE manufacturer " + "( id INTEGER PRIMARY KEY %1, " + " name VARCHAR(255) NOT NULL, " + " address VARCHAR(2000), " + " url VARCHAR(255), " + " email VARCHAR(255), " + " phone VARCHAR(255), " + " fax VARCHAR(255), " + " comment VARCHAR(2000) " + ");").arg(translate("AUTOINCREMENT", m_databaseType)))) + { + myDebug << query.lastError().text(); + return(false); + } + + // DISTRIBUTOR + if(!query.exec(QString("CREATE TABLE distributor " + "( id INTEGER PRIMARY KEY %1, " + " name VARCHAR(255) NOT NULL, " + " address VARCHAR(2000), " + " url VARCHAR(255), " + " email VARCHAR(255), " + " phone VARCHAR(255), " + " fax VARCHAR(255), " + " comment VARCHAR(2000) " + ");").arg(translate("AUTOINCREMENT", m_databaseType)))) + { + myDebug << query.lastError().text(); + return(false); + } + + // STORAGE_CATEGORY + if(!query.exec(QString("CREATE TABLE storage_category " + "( id INTEGER PRIMARY KEY %1, " + " parent INTEGER, " + " name VARCHAR(255) NOT NULL, " + " description VARCHAR(2000), " + " CONSTRAINT FK_storage_category_id FOREIGN KEY (parent) REFERENCES storage_category(id) " + ");").arg(translate("AUTOINCREMENT", m_databaseType)))) + { + myDebug << query.lastError().text(); + return(false); + } + + // STORAGE + if(!query.exec(QString("CREATE TABLE storage " + "( id INTEGER PRIMARY KEY %1, " + " storage_category_id INTEGER, " + " name VARCHAR(255) NOT NULL, " + " description VARCHAR(2000), " + " CONSTRAINT FK_storage_storage_category_id FOREIGN KEY (storage_category_id) REFERENCES storage_category(id) " + ");").arg(translate("AUTOINCREMENT", m_databaseType)))) + { + myDebug << query.lastError().text(); + return(false); + } + + return(true); +} + +bool cDatabase::upgradeDB(const QString& /*version*/) +{ + return(true); +} diff --git a/cdatabase.h b/cdatabase.h new file mode 100644 index 0000000..8ccbb13 --- /dev/null +++ b/cdatabase.h @@ -0,0 +1,47 @@ +#ifndef CDATABASE_H +#define CDATABASE_H + + +#include +#include +#include +#include + + +typedef struct tagSQLTRANSLATE +{ + QString sql; + QString dbType; + QString translated; +} SQLTRANSLATE; + + +class cDatabase +{ +public: + cDatabase(); + ~cDatabase(); + + bool connect(); + + QSqlDatabase db(); +private: + QString m_databaseType; + QString m_hostName; + qint16 m_port; + QString m_databaseName; + QString m_userName; + QString m_password; + QSqlDatabase m_db; + + QList m_sqlTranslate; + + void addTranslate(const QString& sql, const QString& dbType, const QString& translated); + QString translate(const QString& sql, const QString& dbType); + + bool checkDB(); + bool createTables(); + bool upgradeDB(const QString& version); +}; + +#endif // CDATABASE_H diff --git a/cdistributor.cpp b/cdistributor.cpp new file mode 100644 index 0000000..b50fc9e --- /dev/null +++ b/cdistributor.cpp @@ -0,0 +1,364 @@ +#include "cdistributor.h" + +#include +#include + +#include + +#include "common.h" + + +cDistributor::cDistributor(cDatabase* db, qint32 id, QObject* parent) : + QObject(parent), + m_db(db), + m_changed(false), + m_id(id), + m_name(""), + m_address(""), + m_url(""), + m_email(""), + m_comment(""), + m_phone(""), + m_fax(""), + m_item(nullptr) +{ +} + +cDistributor::cDistributor(cDistributor* distributor) +{ + set(distributor); +} + +void cDistributor::set(cDistributor* distributor) +{ + m_db = distributor->db(); + m_id = distributor->id(); + m_name = distributor->name(); + m_address = distributor->address(); + m_url = distributor->url(); + m_email = distributor->email(); + m_comment = distributor->comment(); + m_phone = distributor->phone(); + m_fax = distributor->fax(); +} + +void cDistributor::setID(const qint32& id) +{ + m_id = id; + m_changed = true; + emit idChanged(id); + emit distributorChanged(this); +} + +qint32 cDistributor::id() +{ + return(m_id); +} + +void cDistributor::setName(const QString& name) +{ + m_name = name; + m_changed = true; + emit nameChanged(name); + emit distributorChanged(this); +} + +QString cDistributor::name() +{ + return(m_name); +} + +void cDistributor::setAddress(const QString& address) +{ + m_address = address; + emit addressChanged(address); + emit distributorChanged(this); +} + +QString cDistributor::address() +{ + return(m_address); +} + +void cDistributor::setURL(const QString& url) +{ + m_url = url; + m_changed = true; + emit urlChanged(url); + emit distributorChanged(this); +} + +QString cDistributor::url() +{ + return(m_url); +} + +void cDistributor::setEmail(const QString& email) +{ + m_email = email; + m_changed = true; + emit emailChanged(email); + emit distributorChanged(this); +} + +QString cDistributor::email() +{ + return(m_email); +} + +void cDistributor::setComment(const QString& comment) +{ + m_comment = comment; + emit commentChanged(comment); + emit distributorChanged(this); +} + +QString cDistributor::comment() +{ + return(m_comment); +} + +void cDistributor::setPhone(const QString& phone) +{ + m_phone = phone; + m_changed = true; + emit phoneChanged(phone); + emit distributorChanged(this); +} + +QString cDistributor::phone() +{ + return(m_phone); +} + +void cDistributor::setFax(const QString& fax) +{ + m_fax = fax; + m_changed = true; + emit faxChanged(fax); + emit distributorChanged(this); +} + +QString cDistributor::fax() +{ + return(m_fax); +} + +void cDistributor::setItem(QStandardItem* item) +{ + m_item = item; +} + +QStandardItem* cDistributor::item() +{ + return(m_item); +} + +cDatabase* cDistributor::db() +{ + return(m_db); +} + +bool cDistributor::save() +{ + if(!m_changed) + return(true); + + QSqlQuery query; + + if(m_id == -1) + query.prepare("INSERT INTO distributor (name, address, url, email, comment, phone, fax) VALUES (:name, :address, :url, :email, :comment, :phone, :fax);"); + else + query.prepare("UPDATE distributor SET name=:name, address=:address, url=:url, email=:email, comment=:comment, phone=:phone, fax=:fax WHERE id=:id;"); + + query.bindValue(":id", m_id); + query.bindValue(":name", m_name); + query.bindValue(":address", m_address); + query.bindValue(":url", m_url); + query.bindValue(":email", m_email); + query.bindValue(":comment", m_comment); + query.bindValue(":phone", m_phone); + query.bindValue(":fax", m_fax); + + if(!query.exec()) + { + myDebug << query.lastError().text(); + return(false); + } + + if(m_id == -1) + { + if(!query.exec("SELECT MAX(id) MAXID FROM distributor;")) + { + myDebug << query.lastError().text(); + return(false); + } + + query.first(); + m_id = query.value("MAXID").toInt(); + } + m_changed = false; + return(true); +} + +bool cDistributor::remove() +{ + QSqlQuery query; + + query.prepare("DELETE FROM distributor WHERE id=:id;"); + query.bindValue(":id", m_id); + + if(!query.exec()) + { + myDebug << query.lastError().text(); + return(false); + } + + return(true); +} + +void cDistributor::clearSave() +{ + m_changed = false; +} + +cDistributorList::cDistributorList(cDatabase* db, QObject* parent) : + QObject(parent), + m_db(db) +{ +} + +bool cDistributorList::load() +{ + if(!m_db->db().isOpen()) + return(false); + + QString sql = QString("SELECT id, " + " name, " + " address, " + " url, " + " email, " + " comment, " + " phone, " + " fax " + "FROM distributor " + "ORDER BY name;"); + QSqlQuery query(m_db->db()); + + query.prepare(sql); + + if(!query.exec()) + { + myDebug << query.lastError().text(); + return(false); + } + + while(query.next()) + { + cDistributor* lpDistributor = add(query.value("id").toInt()); + lpDistributor->setName(query.value("name").toString()); + lpDistributor->setAddress(query.value("address").toString()); + lpDistributor->setURL(query.value("url").toString()); + lpDistributor->setEmail(query.value("email").toString()); + lpDistributor->setComment(query.value("comment").toString()); + lpDistributor->setPhone(query.value("phone").toString()); + lpDistributor->setFax(query.value("fax").toString()); + } + + return(true); +} + +cDistributor* cDistributorList::add(const qint32& id) +{ + cDistributor* lpNew = find(id); + + if(!lpNew) + { + lpNew = new cDistributor(m_db, id); + append(lpNew); + emit distributorAdded(lpNew); + } + + return(lpNew); +} + +cDistributor* cDistributorList::add(const QString& name) +{ + cDistributor* lpNew = new cDistributor(m_db); + lpNew->setName(name); + append(lpNew); + emit distributorAdded(lpNew); + + return(lpNew); +} + +bool cDistributorList::remove(const qint32& id) +{ + cDistributor* manufacturer = find(id); + if(!manufacturer) + return(false); + + if(!manufacturer->remove()) + return(false); + + if(!removeOne(manufacturer)) + return(false); + + emit distributorRemoved(manufacturer); + + return(true); +} + +cDistributor* cDistributorList::find(const qint32& id) +{ + for(int i = 0;i < count();i++) + { + if(at(i)->id() == id) + return(at(i)); + } + + return(nullptr); +} + +cDistributor* cDistributorList::find(const QString& name) +{ + for(int i = 0;i < count();i++) + { + if(at(i)->name() == name) + return(at(i)); + } + + return(nullptr); +} + +bool cDistributorList::fillList(QStandardItemModel* model) +{ + model->clear(); + + if(!count()) + return(true); + + for(int i = 0;i < count();i++) + { + QStandardItem* item = new QStandardItem; + at(i)->setItem(item); + item->setText(at(i)->name()); + item->setData(QVariant::fromValue(at(i)), ITEM_DISTRIBUTOR_DATA); + model->appendRow(item); + } + + return(true); +} + +bool cDistributorList::save() +{ + bool ret = true; + + for(int i = 0;i < count();i++) + { + if(!at(i)->save()) + ret = false; + } + + return(ret); +} diff --git a/cdistributor.h b/cdistributor.h new file mode 100644 index 0000000..708cd57 --- /dev/null +++ b/cdistributor.h @@ -0,0 +1,108 @@ +#ifndef CDISTRIBUTOR_H +#define CDISTRIBUTOR_H + + +#include "cdatabase.h" + +#include +#include +#include + +#include +#include + + +class cDistributor : public QObject +{ + Q_OBJECT + +public: + explicit cDistributor(cDatabase* db, qint32 id = -1, QObject* parent = nullptr); + cDistributor(cDistributor* distributor); + + void set(cDistributor* distributor); + + void setID(const qint32& id); + qint32 id(); + + void setName(const QString& name); + QString name(); + + void setAddress(const QString& address); + QString address(); + + void setURL(const QString& url); + QString url(); + + void setEmail(const QString& email); + QString email(); + + void setComment(const QString& comment); + QString comment(); + + void setPhone(const QString& phone); + QString phone(); + + void setFax(const QString& fax); + QString fax(); + + void setItem(QStandardItem* item); + QStandardItem* item(); + + bool save(); + void clearSave(); + bool remove(); + + cDatabase* db(); +private: + cDatabase* m_db; + bool m_changed; + qint32 m_id; + QString m_name; + QString m_address; + QString m_url; + QString m_email; + QString m_comment; + QString m_phone; + QString m_fax; + QStandardItem* m_item; +signals: + void distributorChanged(cDistributor* distributor); + void idChanged(const qint32& id); + void nameChanged(const QString& name); + void addressChanged(const QString& address); + void urlChanged(const QString& url); + void emailChanged(const QString& email); + void commentChanged(const QString& comment); + void phoneChanged(const QString& phone); + void faxChanged(const QString& fax); +}; + +Q_DECLARE_METATYPE(cDistributor*) + +class cDistributorList : public QObject, public QList +{ + Q_OBJECT + +public: + cDistributorList(cDatabase* db, QObject* parent = nullptr); + + bool load(); + cDistributor* add(const qint32& id); + cDistributor* add(const QString& name); + bool remove(const qint32& id); + cDistributor* find(const qint32& id); + cDistributor* find(const QString& name); + + bool fillList(QStandardItemModel* model); + + bool save(); +private: + cDatabase* m_db; + +signals: + void distributorAdded(cDistributor* manufacturer); + void distributorRemoved(cDistributor* manufacturer); +}; + +#endif // CDISTRIBUTOR_H diff --git a/cdistributorwindow.cpp b/cdistributorwindow.cpp new file mode 100644 index 0000000..46ee2d6 --- /dev/null +++ b/cdistributorwindow.cpp @@ -0,0 +1,111 @@ +#include "cdistributorwindow.h" +#include "ui_cdistributorwindow.h" + +#include "cmainwindow.h" + + +cDistributorWindow::cDistributorWindow(QWidget *parent) : + cMDISubWindow(parent), + ui(new Ui::cDistributorWindow), + m_distributor(nullptr) +{ + ui->setupUi(this); +} + +cDistributorWindow::~cDistributorWindow() +{ + delete ui; +} + +void cDistributorWindow::setDistributor(cDistributor* distributor) +{ + m_distributor = distributor; + + fillFields(); + + connect(ui->m_name, &QLineEdit::textChanged, this, &cDistributorWindow::onNameChanged); + connect(ui->m_address, &QPlainTextEdit::textChanged, this, &cDistributorWindow::onAddressChanged); + connect(ui->m_url, &QLineEdit::textChanged, this, &cDistributorWindow::onURLChanged); + connect(ui->m_email, &QLineEdit::textChanged, this, &cDistributorWindow::onEmailChanged); + connect(ui->m_phone, &QLineEdit::textChanged, this, &cDistributorWindow::onPhoneChanged); + connect(ui->m_fax, &QLineEdit::textChanged, this, &cDistributorWindow::onFaxChanged); + connect(ui->m_comment, &QPlainTextEdit::textChanged, this, &cDistributorWindow::onCommentChanged); +} + +cDistributor* cDistributorWindow::distributor() +{ + return(m_distributor); +} + +void cDistributorWindow::onDistributorChanged(cDistributor* distributor) +{ + if(m_distributor != distributor) + return; + + fillFields(); +} + +void cDistributorWindow::onNameChanged(const QString& name) +{ + m_distributor->setName(name); + + if(m_distributor->item()) + m_distributor->item()->setText(name); + + emit somethingChanged(); +} + +void cDistributorWindow::onAddressChanged() +{ + m_distributor->setAddress(ui->m_address->toPlainText()); + + emit somethingChanged(); +} + +void cDistributorWindow::onURLChanged(const QString& url) +{ + m_distributor->setURL(url); + + emit somethingChanged(); +} + +void cDistributorWindow::onEmailChanged(const QString& email) +{ + m_distributor->setEmail(email); + + emit somethingChanged(); +} + +void cDistributorWindow::onPhoneChanged(const QString& phone) +{ + m_distributor->setPhone(phone); + + emit somethingChanged(); +} + +void cDistributorWindow::onFaxChanged(const QString& fax) +{ + m_distributor->setFax(fax); + + emit somethingChanged(); +} + +void cDistributorWindow::onCommentChanged() +{ + m_distributor->setComment(ui->m_comment->toPlainText()); + + emit somethingChanged(); +} + +void cDistributorWindow::fillFields() +{ + ui->m_name->setText(m_distributor->name()); + ui->m_address->setPlainText(m_distributor->address()); + ui->m_url->setText(m_distributor->url()); + ui->m_email->setText(m_distributor->email()); + ui->m_phone->setText(m_distributor->phone()); + ui->m_fax->setText(m_distributor->fax()); + ui->m_comment->setPlainText(m_distributor->comment()); + + setWindowTitle("distributor - " + m_distributor->name()); +} diff --git a/cdistributorwindow.h b/cdistributorwindow.h new file mode 100644 index 0000000..5d091f0 --- /dev/null +++ b/cdistributorwindow.h @@ -0,0 +1,50 @@ +#ifndef CDISTRIBUTORWINDOW_H +#define CDISTRIBUTORWINDOW_H + + +#include "cdistributor.h" + +#include "cmdisubwindow.h" +#include "cmainwindow.h" + +#include + + +namespace Ui { +class cDistributorWindow; +} + +class cDistributorWindow : public cMDISubWindow +{ + Q_OBJECT + +public: + explicit cDistributorWindow(QWidget *parent = nullptr); + ~cDistributorWindow(); + + void setDistributor(cDistributor* distributor); + cDistributor* distributor(); + +private: + Ui::cDistributorWindow* ui; + cDistributor* m_distributor; + + void fillFields(); + +public slots: + void onDistributorChanged(cDistributor* distributor); + +private slots: + void onNameChanged(const QString& szName); + void onAddressChanged(); + void onURLChanged(const QString& szURL); + void onEmailChanged(const QString& szEmail); + void onPhoneChanged(const QString& szPhone); + void onFaxChanged(const QString& szFax); + void onCommentChanged(); + +signals: + void somethingChanged(); +}; + +#endif // CDISTRIBUTORWINDOW_H diff --git a/cdistributorwindow.ui b/cdistributorwindow.ui new file mode 100644 index 0000000..0989652 --- /dev/null +++ b/cdistributorwindow.ui @@ -0,0 +1,95 @@ + + + cDistributorWindow + + + + 0 + 0 + 400 + 300 + + + + Distributor - + + + + + + + + Name: + + + + + + + + + + Address: + + + + + + + + + + URL: + + + + + + + + + + Email: + + + + + + + + + + Phone: + + + + + + + + + + Fax: + + + + + + + + + + Comment: + + + + + + + + + + + + + diff --git a/cmainwindow.cpp b/cmainwindow.cpp new file mode 100644 index 0000000..3986f83 --- /dev/null +++ b/cmainwindow.cpp @@ -0,0 +1,726 @@ +#include "cmainwindow.h" +#include "ui_cmainwindow.h" + +#include "cdatabase.h" + +#include "cwidget.h" +#include "cmanufacturerwindow.h" +#include "cdistributorwindow.h" + +#include +#include + +#include + +#include "common.h" + + +cMainWindow::cMainWindow(cSplashScreen* splashScreen, QWidget *parent) + : QMainWindow(parent), + ui(new Ui::cMainWindow), + m_somethingChanged(false), + m_splashScreen(splashScreen), + m_database(nullptr), + m_manufacturerList(nullptr), + m_distributorList(nullptr), + m_storageCategoryList(nullptr), + m_storageList(nullptr), + m_fileMenu(nullptr), + m_fileToolBar(nullptr), + m_fileQuitAction(nullptr), + m_listAdd(nullptr), + m_listEdit(nullptr), + m_listRemove(nullptr), + m_manufacturerListAddAction(nullptr), + m_manufacturerListEditAction(nullptr), + m_manufacturerListRemoveAction(nullptr), + m_distributorListAddAction(nullptr), + m_distributorListEditAction(nullptr), + m_distributorListRemoveAction(nullptr), + m_manufacturerListModel(nullptr), + m_distributorListModel(nullptr), + m_storageListModel(nullptr), + m_updatingTab(false) +{ + initUI(); + createActions(); + + loadData(); + + setListButtonState(); + updateWindowTitle(); +} + +cMainWindow::~cMainWindow() +{ + if(m_manufacturerList) + delete m_manufacturerList; + + if(m_distributorList) + delete m_distributorList; + + if(m_storageCategoryList) + delete m_storageCategoryList; + + if(m_storageList) + delete m_storageList; + + if(m_database) + delete m_database; + + delete ui; +} + +void cMainWindow::closeEvent(QCloseEvent *event) +{ + QSettings settings; + settings.setValue("main/width", QVariant::fromValue(size().width())); + settings.setValue("main/height", QVariant::fromValue(size().height())); + settings.setValue("main/x", QVariant::fromValue(x())); + settings.setValue("main/y", QVariant::fromValue(y())); + if(this->isMaximized()) + settings.setValue("main/maximized", QVariant::fromValue(true)); + else + settings.setValue("main/maximized", QVariant::fromValue(false)); + + QList sizes = ui->m_splitter->sizes(); + + for(int x = 0;x < sizes.count();x++) + settings.setValue(QString("main/splitter%1").arg(x+1), QVariant::fromValue(sizes[x])); + + event->accept(); +} + +void cMainWindow::initUI() +{ + ui->setupUi(this); + + QIcon::setThemeName("TangoMFK"); + + QSettings settings; + + if(!settings.value("main/maximized").toBool()) + { + qint32 iX = settings.value("main/x", QVariant::fromValue(-1)).toInt(); + qint32 iY = settings.value("main/y", QVariant::fromValue(-1)).toInt(); + qint32 iWidth = settings.value("main/width", QVariant::fromValue(-1)).toInt(); + qint32 iHeight = settings.value("main/height", QVariant::fromValue(-1)).toInt(); + + if(iWidth != -1 && iHeight != -1) + resize(iWidth, iHeight); + if(iX != -1 && iY != -1) + move(iX, iY); + } + + qint32 iWidth1 = settings.value("main/splitter1", QVariant::fromValue(-1)).toInt(); + qint32 iWidth2 = settings.value("main/splitter2", QVariant::fromValue(-1)).toInt(); + qint32 iWidth3 = settings.value("main/splitter3", QVariant::fromValue(-1)).toInt(); + + ui->m_splitter->setSizes(QList() << iWidth1 << iWidth2 << iWidth3); + + m_manufacturerListModel = new QStandardItemModel(0, 1); + ui->m_manufacturerList->setModel(m_manufacturerListModel); + + m_distributorListModel = new QStandardItemModel(0, 1); + ui->m_distributorList->setModel(m_distributorListModel); + + m_storageListModel = new QStandardItemModel(0, 1); + ui->m_storageList->setModel(m_storageListModel); + + ui->m_toolBox->setCurrentIndex(0); +} + +void cMainWindow::createActions() +{ + setToolButtonStyle(Qt::ToolButtonFollowStyle); + createFileActions(); + + const QIcon addIcon = QIcon::fromTheme("list-add"); + m_listAdd = new QAction(addIcon, "add", this); + ui->m_listAdd->setDefaultAction(m_listAdd); + connect(m_listAdd, &QAction::triggered, this, &cMainWindow::onListAdd); + + const QIcon editIcon = QIcon::fromTheme("accessories-text-editor"); + m_listEdit = new QAction(editIcon, "edit", this); + ui->m_listEdit->setDefaultAction(m_listEdit); + connect(m_listEdit, &QAction::triggered, this, &cMainWindow::onListEdit); + + const QIcon removeIcon = QIcon::fromTheme("list-remove"); + m_listRemove = new QAction(removeIcon, "remove", this); + ui->m_listRemove->setDefaultAction(m_listRemove); + connect(m_listRemove, &QAction::triggered, this, &cMainWindow::onListRemove); + + connect(ui->m_toolBox, &QToolBox::currentChanged, this, &cMainWindow::onToolBoxCurrentChanged); + + connect(ui->m_manufacturerList, &QTreeView::clicked, this, &cMainWindow::onManufacturerListClicked); + connect(ui->m_manufacturerList, &QTreeView::doubleClicked, this, &cMainWindow::onManufacturerListDoubleClicked); + connect(m_manufacturerListModel, &QStandardItemModel::itemChanged, this, &cMainWindow::onManufacturerListNameChanged); + connect(ui->m_manufacturerList, &QTreeView::customContextMenuRequested, this, &cMainWindow::onManufacturerListContextMenu); + + connect(ui->m_distributorList, &QTreeView::clicked, this, &cMainWindow::onDistributorListClicked); + connect(ui->m_distributorList, &QTreeView::doubleClicked, this, &cMainWindow::onDistributorListDoubleClicked); + connect(m_distributorListModel, &QStandardItemModel::itemChanged, this, &cMainWindow::onDistributorListNameChanged); + connect(ui->m_distributorList, &QTreeView::customContextMenuRequested, this, &cMainWindow::onDistributorListContextMenu); + + connect(ui->m_mainTab, &QTabWidget::currentChanged, this, &cMainWindow::onMainTabCurrentChanged); + connect(ui->m_mainTab, &QTabWidget::tabCloseRequested, this, &cMainWindow::onMainTabTabCloseRequested); + connect(ui->m_mdiArea, &QMdiArea::subWindowActivated, this, &cMainWindow::onMdiAreaSubWindowActivated); + + createContextActions(); +} + +void cMainWindow::createContextActions() +{ + m_manufacturerListAddAction = new QAction(tr("add..."), this); + connect(m_manufacturerListAddAction, &QAction::triggered, this, &cMainWindow::onManufacturerListAddClicked); + + m_manufacturerListEditAction = new QAction(tr("edit..."), this); + connect(m_manufacturerListEditAction, &QAction::triggered, this, &cMainWindow::onManufacturerListEditClicked); + + m_manufacturerListRemoveAction = new QAction(tr("remove..."), this); + connect(m_manufacturerListRemoveAction, &QAction::triggered, this, &cMainWindow::onManufacturerListRemoveClicked); + + m_distributorListAddAction = new QAction(tr("add..."), this); + connect(m_distributorListAddAction, &QAction::triggered, this, &cMainWindow::onDistributorListAddClicked); + + m_distributorListEditAction = new QAction(tr("edit..."), this); + connect(m_distributorListEditAction, &QAction::triggered, this, &cMainWindow::onDistributorListEditClicked); + + m_distributorListRemoveAction = new QAction(tr("remove..."), this); + connect(m_distributorListRemoveAction, &QAction::triggered, this, &cMainWindow::onDistributorListRemoveClicked); +} + +void cMainWindow::createFileActions() +{ + m_fileMenu = menuBar()->addMenu(tr("&File")); + m_fileToolBar = addToolBar(tr("File Actions")); + + m_fileSaveAction = m_fileMenu->addAction(tr("&Save"), this, &cMainWindow::onFileSave); + m_fileSaveAction->setShortcut(Qt::CTRL | Qt::Key_S); + + m_fileMenu->addSeparator(); + + m_fileQuitAction = m_fileMenu->addAction(tr("&Quit"), this, &QWidget::close); + m_fileQuitAction->setShortcut(Qt::CTRL | Qt::Key_Q); +} + +void cMainWindow::loadData() +{ + m_database = new cDatabase(); + m_database->connect(); + + m_manufacturerList = new cManufacturerList(m_database); + m_manufacturerList->load(); + m_manufacturerList->fillList(m_manufacturerListModel); + + m_distributorList = new cDistributorList(m_database); + m_distributorList->load(); + m_distributorList->fillList(m_distributorListModel); + + m_storageCategoryList = new cStorageCategoryList(m_database); + m_storageCategoryList->load(); + m_storageCategoryList->fillList(m_storageListModel); + + m_storageList = new cStorageList(m_database, m_storageCategoryList); + m_storageList->load(); + m_storageList->fillList(); +} + +void cMainWindow::setListButtonState() +{ + switch(activeTab()) + { + case TAB_MANUFACTURER_LIST: + if(ui->m_manufacturerList->selectionModel()->selectedRows().count()) + { + m_listEdit->setEnabled(true); + m_listRemove->setEnabled(true); + } + else + { + m_listEdit->setEnabled(false); + m_listRemove->setEnabled(false); + } + break; + case TAB_DISTRIBUTOR_LIST: + if(ui->m_distributorList->selectionModel()->selectedRows().count()) + { + m_listEdit->setEnabled(true); + m_listRemove->setEnabled(true); + } + else + { + m_listEdit->setEnabled(false); + m_listRemove->setEnabled(false); + } + break; + case TAB_PART_LIST: + { + m_listEdit->setEnabled(false); + m_listRemove->setEnabled(false); + } + break; + case TAB_PROJECT_LIST: + { + m_listEdit->setEnabled(false); + m_listRemove->setEnabled(false); + } + break; + } + + m_listAdd->setEnabled(true); +} + +void cMainWindow::onFileSave() +{ + if(m_manufacturerList->save()) + { + m_somethingChanged = false; + updateWindowTitle(); + } + + if(m_distributorList->save()) + { + m_somethingChanged = false; + updateWindowTitle(); + } + + if(m_storageList->save()) + { + m_somethingChanged = false; + updateWindowTitle(); + } + + if(m_storageCategoryList->save()) + { + m_somethingChanged = false; + updateWindowTitle(); + } +} + +void cMainWindow::onSomethingChanged() +{ + if(!m_somethingChanged) + { + m_somethingChanged = true; + updateWindowTitle(); + } +} + +void cMainWindow::onToolBoxCurrentChanged(int /*index*/) +{ + setListButtonState(); +} + +void cMainWindow::onMainTabCurrentChanged(int /*index*/) +{ + if(m_updatingTab) + return; + + m_updatingTab = true; + cWidget* lpWidget = static_cast(ui->m_mainTab->currentWidget()); + QMdiSubWindow* lpWindow = lpWidget->window(); + ui->m_mdiArea->setActiveSubWindow(lpWindow); + m_updatingTab = false; +} + +void cMainWindow::onMainTabTabCloseRequested(int index) +{ + if(m_updatingTab) + return; + + m_updatingTab = true; +// disconnectTextEdit(); +// m_lpOldTextEdit = nullptr; + cWidget* lpWidget = static_cast(ui->m_mainTab->currentWidget()); + QMdiSubWindow* lpWindow = lpWidget->window(); + ui->m_mainTab->removeTab(index); + ui->m_mdiArea->removeSubWindow(lpWindow); + delete(lpWidget); + m_updatingTab = false; +} + +void cMainWindow::onMdiAreaSubWindowActivated(QMdiSubWindow *arg1) +{ + if(m_updatingTab) + return; + + m_updatingTab = true; + + for(int x = 0;x < ui->m_mainTab->count();x++) + { + cWidget* lpWidget = static_cast(ui->m_mainTab->widget(x)); + if(lpWidget->window() == arg1) + { + ui->m_mainTab->setCurrentIndex(x); + m_updatingTab = false; + return; + } + } + m_updatingTab = false; +} + +void cMainWindow::onSubWindowClosed(QWidget* lpSubWindow) +{ + if(m_updatingTab) + return; + + m_updatingTab = true; +// disconnectTextEdit(); +// m_lpOldTextEdit = nullptr; + + for(int x = 0;x < ui->m_mainTab->count();x++) + { + cWidget* lpWidget = static_cast(ui->m_mainTab->widget(x)); + if(lpWidget->widget() == lpSubWindow) + { + ui->m_mainTab->removeTab(x); + m_updatingTab = false; + return; + } + } + m_updatingTab = false; +} + +void cMainWindow::onManufacturerListClicked(const QModelIndex& /*index*/) +{ + setListButtonState(); +} + +void cMainWindow::onManufacturerListDoubleClicked(const QModelIndex& /*index*/) +{ + editManufacturer(); +} + +void cMainWindow::onManufacturerListContextMenu(const QPoint& pos) +{ + QMenu* menu = new QMenu(this); + + menu->addAction(m_manufacturerListAddAction); + + QStandardItem* item = nullptr; + + if(ui->m_manufacturerList->selectionModel()->selectedRows().count()) + item = m_manufacturerListModel->itemFromIndex(ui->m_manufacturerList->currentIndex()); + if(item) + { + menu->addAction(m_manufacturerListEditAction); + menu->addAction(m_manufacturerListRemoveAction); + } + + menu->exec(ui->m_manufacturerList->mapToGlobal(pos)); +} + +void cMainWindow::onManufacturerListNameChanged(QStandardItem* item) +{ + cManufacturer* manufacturer = item->data(ITEM_MANUFACTURER_DATA).value(); + QString name = item->text(); + + if(name.isEmpty()) + { + item->setText(manufacturer->name()); + return; + } + + if(name != manufacturer->name()) + { + onSomethingChanged(); + manufacturer->setName(name); + emit manufacturerNameChanged(manufacturer); + } +} + +void cMainWindow::onDistributorListClicked(const QModelIndex& /*index*/) +{ + setListButtonState(); +} + +void cMainWindow::onDistributorListDoubleClicked(const QModelIndex& /*index*/) +{ + editDistributor(); +} + +void cMainWindow::onDistributorListContextMenu(const QPoint& pos) +{ + QMenu* menu = new QMenu(this); + + menu->addAction(m_distributorListAddAction); + + QStandardItem* item = nullptr; + + if(ui->m_distributorList->selectionModel()->selectedRows().count()) + item = m_distributorListModel->itemFromIndex(ui->m_distributorList->currentIndex()); + if(item) + { + menu->addAction(m_distributorListEditAction); + menu->addAction(m_distributorListRemoveAction); + } + + menu->exec(ui->m_distributorList->mapToGlobal(pos)); +} + +void cMainWindow::onDistributorListNameChanged(QStandardItem* item) +{ + cDistributor* distributor = item->data(ITEM_DISTRIBUTOR_DATA).value(); + QString name = item->text(); + + if(name.isEmpty()) + { + item->setText(distributor->name()); + return; + } + + if(name != distributor->name()) + { + onSomethingChanged(); + distributor->setName(name); + emit distributorNameChanged(distributor); + } +} + +void cMainWindow::onListAdd() +{ + switch(activeTab()) + { + case TAB_MANUFACTURER_LIST: + addManufacturer(); + break; + case TAB_DISTRIBUTOR_LIST: + addDistributor(); + break; + } +} + +void cMainWindow::onListEdit() +{ + switch(activeTab()) + { + case TAB_MANUFACTURER_LIST: + editManufacturer(); + break; + } + switch(activeTab()) + { + case TAB_DISTRIBUTOR_LIST: + editDistributor(); + break; + } +} + +void cMainWindow::onListRemove() +{ + switch(activeTab()) + { + case TAB_MANUFACTURER_LIST: + removeManufacturer(); + break; + } + switch(activeTab()) + { + case TAB_DISTRIBUTOR_LIST: + removeDistributor(); + break; + } +} + +void cMainWindow::onManufacturerListAddClicked() +{ + addManufacturer(); +} + +void cMainWindow::onManufacturerListEditClicked() +{ + editManufacturer(); +} + +void cMainWindow::onManufacturerListRemoveClicked() +{ + removeManufacturer(); +} + +void cMainWindow::onDistributorListAddClicked() +{ + addDistributor(); +} + +void cMainWindow::onDistributorListEditClicked() +{ + editDistributor(); +} + +void cMainWindow::onDistributorListRemoveClicked() +{ + removeDistributor(); +} + +qint16 cMainWindow::activeTab() +{ + QWidget* widget = ui->m_toolBox->currentWidget(); + + if(widget == ui->m_manufacturerListTab) + return(TAB_MANUFACTURER_LIST); + else if(widget == ui->m_distributorListTab) + return(TAB_DISTRIBUTOR_LIST); + else if(widget == ui->m_partListTab) + return(TAB_PART_LIST); + else if(widget == ui->m_projectListTab) + return(TAB_PROJECT_LIST); + + return(0); +} + +void cMainWindow::updateWindowTitle() +{ + QString windowTitle = ""; + + if(m_somethingChanged) + windowTitle = "unsaved"; + + m_fileSaveAction->setEnabled(m_somethingChanged); + + setWindowTitle(windowTitle); +} + +void cMainWindow::addManufacturer() +{ + bool ok; + QString name = QInputDialog::getText(this, tr("New Manufacturer"), tr("Name:"), QLineEdit::Normal, "", &ok); + if(!ok) + return; + + cManufacturer* manufacturer = m_manufacturerList->add(name); + + QStandardItem* item = new QStandardItem(name); + item->setData(QVariant::fromValue(manufacturer), ITEM_MANUFACTURER_DATA); + m_manufacturerListModel->appendRow(item); + m_manufacturerListModel->sort(Qt::AscendingOrder | Qt::CaseInsensitive); + + onSomethingChanged(); +} + +void cMainWindow::editManufacturer() +{ + if(!ui->m_manufacturerList->selectionModel()->selectedIndexes().count()) + return; + + QModelIndex index = ui->m_manufacturerList->selectionModel()->selectedIndexes()[0]; + QStandardItem* item = m_manufacturerListModel->itemFromIndex(index); + cManufacturer* manufacturer = item->data(ITEM_MANUFACTURER_DATA).value(); + + for(int x = 0;x < ui->m_mainTab->count();x++) + { + cWidget* widget = static_cast(ui->m_mainTab->widget(x)); + if(widget->type() == cWidget::TYPE_manufacturer) + { + cManufacturerWindow* manufacturerWindow = static_cast(widget->widget()); + if(manufacturerWindow->manufacturer() == manufacturer) + { + ui->m_mainTab->setCurrentIndex(x); + ui->m_mdiArea->setActiveSubWindow(widget->window()); + m_updatingTab = false; + return; + } + } + } + + cManufacturerWindow* manufacturerWindow = new cManufacturerWindow(this); + manufacturerWindow->setManufacturer(manufacturer); + cWidget* widget1 = new cWidget(manufacturerWindow); + widget1->setWindow(ui->m_mdiArea->addSubWindow(manufacturerWindow)); + ui->m_mainTab->addTab(static_cast(widget1), manufacturerWindow->windowTitle()); + manufacturerWindow->show(); + + connect(manufacturerWindow, &cManufacturerWindow::somethingChanged, this, &cMainWindow::onSomethingChanged); + connect(this, &cMainWindow::manufacturerNameChanged, manufacturerWindow, &cManufacturerWindow::onManufacturerChanged); + connect(manufacturerWindow, &cManufacturerWindow::subWindowClosed, this, &cMainWindow::onSubWindowClosed); +} + +void cMainWindow::removeManufacturer() +{ + if(!ui->m_manufacturerList->selectionModel()->selectedIndexes().count()) + return; + + QModelIndex index = ui->m_manufacturerList->selectionModel()->selectedIndexes()[0]; + QStandardItem* item = m_manufacturerListModel->itemFromIndex(index); + cManufacturer* manufacturer = item->data(ITEM_MANUFACTURER_DATA).value(); + + if(QMessageBox::question(this, tr("Remove Manufacturer"), QString(tr("Are you sure you want to remove \"%1\"?")).arg(manufacturer->name())) == QMessageBox::No) + return; + + if(!manufacturer->remove()) + return; + + m_manufacturerListModel->removeRow(index.row()); +} + +void cMainWindow::addDistributor() +{ + bool ok; + QString name = QInputDialog::getText(this, tr("New Distributor"), tr("Name:"), QLineEdit::Normal, "", &ok); + if(!ok) + return; + + cDistributor* distributor = m_distributorList->add(name); + + QStandardItem* item = new QStandardItem(name); + item->setData(QVariant::fromValue(distributor), ITEM_DISTRIBUTOR_DATA); + m_distributorListModel->appendRow(item); + m_distributorListModel->sort(Qt::AscendingOrder | Qt::CaseInsensitive); + + onSomethingChanged(); +} + +void cMainWindow::editDistributor() +{ + if(!ui->m_distributorList->selectionModel()->selectedIndexes().count()) + return; + + QModelIndex index = ui->m_distributorList->selectionModel()->selectedIndexes()[0]; + QStandardItem* item = m_distributorListModel->itemFromIndex(index); + cDistributor* distributor = item->data(ITEM_DISTRIBUTOR_DATA).value(); + + for(int x = 0;x < ui->m_mainTab->count();x++) + { + cWidget* widget = static_cast(ui->m_mainTab->widget(x)); + if(widget->type() == cWidget::TYPE_distributor) + { + cDistributorWindow* distributorWindow = static_cast(widget->widget()); + if(distributorWindow->distributor() == distributor) + { + ui->m_mainTab->setCurrentIndex(x); + ui->m_mdiArea->setActiveSubWindow(widget->window()); + m_updatingTab = false; + return; + } + } + } + + cDistributorWindow* distributorWindow = new cDistributorWindow(this); + distributorWindow->setDistributor(distributor); + cWidget* widget1 = new cWidget(distributorWindow); + widget1->setWindow(ui->m_mdiArea->addSubWindow(distributorWindow)); + ui->m_mainTab->addTab(static_cast(widget1), distributorWindow->windowTitle()); + distributorWindow->show(); + + connect(distributorWindow, &cDistributorWindow::somethingChanged, this, &cMainWindow::onSomethingChanged); + connect(this, &cMainWindow::distributorNameChanged, distributorWindow, &cDistributorWindow::onDistributorChanged); + connect(distributorWindow, &cDistributorWindow::subWindowClosed, this, &cMainWindow::onSubWindowClosed); +} + +void cMainWindow::removeDistributor() +{ + if(!ui->m_distributorList->selectionModel()->selectedIndexes().count()) + return; + + QModelIndex index = ui->m_distributorList->selectionModel()->selectedIndexes()[0]; + QStandardItem* item = m_distributorListModel->itemFromIndex(index); + cDistributor* distributor = item->data(ITEM_DISTRIBUTOR_DATA).value(); + + if(QMessageBox::question(this, tr("Remove distributor"), QString(tr("Are you sure you want to remove \"%1\"?")).arg(distributor->name())) == QMessageBox::No) + return; + + if(!distributor->remove()) + return; + + m_distributorListModel->removeRow(index.row()); +} diff --git a/cmainwindow.h b/cmainwindow.h new file mode 100644 index 0000000..76d4b32 --- /dev/null +++ b/cmainwindow.h @@ -0,0 +1,130 @@ +#ifndef CMAINWINDOW_H +#define CMAINWINDOW_H + + +#include "csplashscreen.h" + +#include "cdatabase.h" +#include "cmanufacturer.h" +#include "cdistributor.h" +#include "cstoragecategory.h" +#include "cstorage.h" + +#include +#include +#include +#include + + +QT_BEGIN_NAMESPACE +namespace Ui { class cMainWindow; } +QT_END_NAMESPACE + +class cMainWindow : public QMainWindow +{ + Q_OBJECT + +public: + cMainWindow(cSplashScreen* splashScreen, QWidget *parent = nullptr); + ~cMainWindow(); + +private: + Ui::cMainWindow* ui; + + bool m_somethingChanged; + + cSplashScreen* m_splashScreen; + cDatabase* m_database; + cManufacturerList* m_manufacturerList; + cDistributorList* m_distributorList; + cStorageCategoryList* m_storageCategoryList; + cStorageList* m_storageList; + + QMenu* m_fileMenu; + + QToolBar* m_fileToolBar; + + QAction* m_fileSaveAction; + QAction* m_fileQuitAction; + + QAction* m_listAdd; + QAction* m_listEdit; + QAction* m_listRemove; + + QAction* m_manufacturerListAddAction; + QAction* m_manufacturerListEditAction; + QAction* m_manufacturerListRemoveAction; + + QAction* m_distributorListAddAction; + QAction* m_distributorListEditAction; + QAction* m_distributorListRemoveAction; + + QStandardItemModel* m_manufacturerListModel; + QStandardItemModel* m_distributorListModel; + QStandardItemModel* m_storageListModel; + + bool m_updatingTab; + + + void initUI(); + void createActions(); + void createFileActions(); + void createContextActions(); + + void loadData(); + + void setListButtonState(); + + qint16 activeTab(); + + void updateWindowTitle(); + + void addManufacturer(); + void editManufacturer(); + void removeManufacturer(); + + void addDistributor(); + void editDistributor(); + void removeDistributor(); + +protected: + void closeEvent(QCloseEvent* event); + +private slots: + void onSomethingChanged(); + + void onToolBoxCurrentChanged(int index); + + void onFileSave(); + + void onMainTabCurrentChanged(int index); + void onMainTabTabCloseRequested(int index); + void onMdiAreaSubWindowActivated(QMdiSubWindow *arg1); + void onSubWindowClosed(QWidget* lpSubWindow); + + void onManufacturerListClicked(const QModelIndex& index); + void onManufacturerListDoubleClicked(const QModelIndex& index); + void onManufacturerListContextMenu(const QPoint& pos); + void onManufacturerListNameChanged(QStandardItem* item); + void onManufacturerListAddClicked(); + void onManufacturerListEditClicked(); + void onManufacturerListRemoveClicked(); + + void onDistributorListClicked(const QModelIndex& index); + void onDistributorListDoubleClicked(const QModelIndex& index); + void onDistributorListContextMenu(const QPoint& pos); + void onDistributorListNameChanged(QStandardItem* item); + void onDistributorListAddClicked(); + void onDistributorListEditClicked(); + void onDistributorListRemoveClicked(); + + void onListAdd(); + void onListEdit(); + void onListRemove(); + +signals: + void manufacturerNameChanged(cManufacturer* manufacturer); + void distributorNameChanged(cDistributor* distributor); +}; + +#endif // CMAINWINDOW_H diff --git a/cmainwindow.ui b/cmainwindow.ui new file mode 100644 index 0000000..01f4b98 --- /dev/null +++ b/cmainwindow.ui @@ -0,0 +1,240 @@ + + + cMainWindow + + + + 0 + 0 + 800 + 600 + + + + + + + + + + + Qt::Horizontal + + + + + + + + + + + + Qt::ToolButtonIconOnly + + + + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 2 + + + + + 0 + 0 + 89 + 362 + + + + Manufacturer + + + + + + Qt::CustomContextMenu + + + QAbstractItemView::EditKeyPressed + + + false + + + false + + + + + + + + + 0 + 0 + 89 + 362 + + + + Distributor + + + + + + Qt::CustomContextMenu + + + QAbstractItemView::EditKeyPressed + + + false + + + true + + + + + + + + + 0 + 0 + 89 + 362 + + + + Storage + + + + + + true + + + false + + + + + + + + + 0 + 0 + 89 + 362 + + + + Part + + + + + + 0 + 0 + 89 + 362 + + + + Project + + + + + + + + + + + + -1 + + + true + + + true + + + true + + + + + + + + + + + + + + + + 0 + 0 + 800 + 21 + + + + + + + toolBar + + + TopToolBarArea + + + false + + + + + + diff --git a/cmanufacturer.cpp b/cmanufacturer.cpp new file mode 100644 index 0000000..e07a9b5 --- /dev/null +++ b/cmanufacturer.cpp @@ -0,0 +1,364 @@ +#include "cmanufacturer.h" + +#include +#include + +#include + +#include "common.h" + + +cManufacturer::cManufacturer(cDatabase* db, qint32 id, QObject* parent) : + QObject(parent), + m_db(db), + m_changed(false), + m_id(id), + m_name(""), + m_address(""), + m_url(""), + m_email(""), + m_comment(""), + m_phone(""), + m_fax(""), + m_item(nullptr) +{ +} + +cManufacturer::cManufacturer(cManufacturer* manufacturer) +{ + set(manufacturer); +} + +void cManufacturer::set(cManufacturer* manufacturer) +{ + m_db = manufacturer->db(); + m_id = manufacturer->id(); + m_name = manufacturer->name(); + m_address = manufacturer->address(); + m_url = manufacturer->url(); + m_email = manufacturer->email(); + m_comment = manufacturer->comment(); + m_phone = manufacturer->phone(); + m_fax = manufacturer->fax(); +} + +void cManufacturer::setID(const qint32& id) +{ + m_id = id; + m_changed = true; + emit idChanged(id); + emit manufacturerChanged(this); +} + +qint32 cManufacturer::id() +{ + return(m_id); +} + +void cManufacturer::setName(const QString& name) +{ + m_name = name; + m_changed = true; + emit nameChanged(name); + emit manufacturerChanged(this); +} + +QString cManufacturer::name() +{ + return(m_name); +} + +void cManufacturer::setAddress(const QString& address) +{ + m_address = address; + emit addressChanged(address); + emit manufacturerChanged(this); +} + +QString cManufacturer::address() +{ + return(m_address); +} + +void cManufacturer::setURL(const QString& url) +{ + m_url = url; + m_changed = true; + emit urlChanged(url); + emit manufacturerChanged(this); +} + +QString cManufacturer::url() +{ + return(m_url); +} + +void cManufacturer::setEmail(const QString& email) +{ + m_email = email; + m_changed = true; + emit emailChanged(email); + emit manufacturerChanged(this); +} + +QString cManufacturer::email() +{ + return(m_email); +} + +void cManufacturer::setComment(const QString& comment) +{ + m_comment = comment; + emit commentChanged(comment); + emit manufacturerChanged(this); +} + +QString cManufacturer::comment() +{ + return(m_comment); +} + +void cManufacturer::setPhone(const QString& phone) +{ + m_phone = phone; + m_changed = true; + emit phoneChanged(phone); + emit manufacturerChanged(this); +} + +QString cManufacturer::phone() +{ + return(m_phone); +} + +void cManufacturer::setFax(const QString& fax) +{ + m_fax = fax; + m_changed = true; + emit faxChanged(fax); + emit manufacturerChanged(this); +} + +QString cManufacturer::fax() +{ + return(m_fax); +} + +void cManufacturer::setItem(QStandardItem* item) +{ + m_item = item; +} + +QStandardItem* cManufacturer::item() +{ + return(m_item); +} + +bool cManufacturer::save() +{ + if(!m_changed) + return(true); + + QSqlQuery query(m_db->db()); + + if(m_id == -1) + query.prepare("INSERT INTO manufacturer (name, address, url, email, comment, phone, fax) VALUES (:name, :address, :url, :email, :comment, :phone, :fax);"); + else + query.prepare("UPDATE manufacturer SET name=:name, address=:address, url=:url, email=:email, comment=:comment, phone=:phone, fax=:fax WHERE id=:id;"); + + query.bindValue(":id", m_id); + query.bindValue(":name", m_name); + query.bindValue(":address", m_address); + query.bindValue(":url", m_url); + query.bindValue(":email", m_email); + query.bindValue(":comment", m_comment); + query.bindValue(":phone", m_phone); + query.bindValue(":fax", m_fax); + + if(!query.exec()) + { + myDebug << query.lastError().text(); + return(false); + } + + if(m_id == -1) + { + if(!query.exec("SELECT MAX(id) MAXID FROM manufacturer;")) + { + myDebug << query.lastError().text(); + return(false); + } + + query.first(); + m_id = query.value("MAXID").toInt(); + } + m_changed = false; + return(true); +} + +cDatabase* cManufacturer::db() +{ + return(m_db); +} + +bool cManufacturer::remove() +{ + QSqlQuery query(m_db->db()); + + query.prepare("DELETE FROM manufacturer WHERE id=:id;"); + query.bindValue(":id", m_id); + + if(!query.exec()) + { + myDebug << query.lastError().text(); + return(false); + } + + return(true); +} + +void cManufacturer::clearSave() +{ + m_changed = false; +} + +cManufacturerList::cManufacturerList(cDatabase* db, QObject* parent) : + QObject(parent), + m_db(db) +{ +} + +bool cManufacturerList::load() +{ + if(!m_db->db().isOpen()) + return(false); + + QString sql = QString("SELECT id, " + " name, " + " address, " + " url, " + " email, " + " comment, " + " phone, " + " fax " + "FROM manufacturer " + "ORDER BY name;"); + QSqlQuery query(m_db->db()); + + query.prepare(sql); + + if(!query.exec()) + { + myDebug << query.lastError().text(); + return(false); + } + + while(query.next()) + { + cManufacturer* lpManufacturer = add(query.value("id").toInt()); + lpManufacturer->setName(query.value("name").toString()); + lpManufacturer->setAddress(query.value("address").toString()); + lpManufacturer->setURL(query.value("url").toString()); + lpManufacturer->setEmail(query.value("email").toString()); + lpManufacturer->setComment(query.value("comment").toString()); + lpManufacturer->setPhone(query.value("phone").toString()); + lpManufacturer->setFax(query.value("fax").toString()); + } + + return(true); +} + +cManufacturer* cManufacturerList::add(const qint32& id) +{ + cManufacturer* lpNew = find(id); + + if(!lpNew) + { + lpNew = new cManufacturer(m_db, id); + append(lpNew); + emit manufacturerAdded(lpNew); + } + + return(lpNew); +} + +cManufacturer* cManufacturerList::add(const QString& name) +{ + cManufacturer* lpNew = new cManufacturer(m_db); + lpNew->setName(name); + append(lpNew); + emit manufacturerAdded(lpNew); + + return(lpNew); +} + +bool cManufacturerList::remove(const qint32& id) +{ + cManufacturer* manufacturer = find(id); + if(!manufacturer) + return(false); + + if(!manufacturer->remove()) + return(false); + + if(!removeOne(manufacturer)) + return(false); + + emit manufacturerRemoved(manufacturer); + + return(true); +} + +cManufacturer* cManufacturerList::find(const qint32& id) +{ + for(int i = 0;i < count();i++) + { + if(at(i)->id() == id) + return(at(i)); + } + + return(nullptr); +} + +cManufacturer* cManufacturerList::find(const QString& name) +{ + for(int i = 0;i < count();i++) + { + if(at(i)->name() == name) + return(at(i)); + } + + return(nullptr); +} + +bool cManufacturerList::fillList(QStandardItemModel* model) +{ + model->clear(); + + if(!count()) + return(true); + + for(int i = 0;i < count();i++) + { + QStandardItem* item = new QStandardItem; + at(i)->setItem(item); + item->setText(at(i)->name()); + item->setData(QVariant::fromValue(at(i)), ITEM_MANUFACTURER_DATA); + model->appendRow(item); + } + + return(true); +} + +bool cManufacturerList::save() +{ + bool ret = true; + + for(int i = 0;i < count();i++) + { + if(!at(i)->save()) + ret = false; + } + + return(ret); +} diff --git a/cmanufacturer.h b/cmanufacturer.h new file mode 100644 index 0000000..b5e94c0 --- /dev/null +++ b/cmanufacturer.h @@ -0,0 +1,108 @@ +#ifndef CMANUFACTURER_H +#define CMANUFACTURER_H + + +#include "cdatabase.h" + +#include +#include +#include + +#include +#include + + +class cManufacturer : public QObject +{ + Q_OBJECT + +public: + explicit cManufacturer(cDatabase* db, qint32 id = -1, QObject* parent = nullptr); + cManufacturer(cManufacturer* manufacturer); + + void set(cManufacturer* manufacturer); + + void setID(const qint32& id); + qint32 id(); + + void setName(const QString& name); + QString name(); + + void setAddress(const QString& address); + QString address(); + + void setURL(const QString& url); + QString url(); + + void setEmail(const QString& email); + QString email(); + + void setComment(const QString& comment); + QString comment(); + + void setPhone(const QString& phone); + QString phone(); + + void setFax(const QString& fax); + QString fax(); + + void setItem(QStandardItem* item); + QStandardItem* item(); + + bool save(); + void clearSave(); + bool remove(); + + cDatabase* db(); +private: + cDatabase* m_db; + bool m_changed; + qint32 m_id; + QString m_name; + QString m_address; + QString m_url; + QString m_email; + QString m_comment; + QString m_phone; + QString m_fax; + QStandardItem* m_item; +signals: + void manufacturerChanged(cManufacturer* manufacturer); + void idChanged(const qint32& id); + void nameChanged(const QString& name); + void addressChanged(const QString& address); + void urlChanged(const QString& url); + void emailChanged(const QString& email); + void commentChanged(const QString& comment); + void phoneChanged(const QString& phone); + void faxChanged(const QString& fax); +}; + +Q_DECLARE_METATYPE(cManufacturer*) + +class cManufacturerList : public QObject, public QList +{ + Q_OBJECT + +public: + cManufacturerList(cDatabase* db, QObject* parent = nullptr); + + bool load(); + cManufacturer* add(const qint32& id); + cManufacturer* add(const QString& name); + bool remove(const qint32& id); + cManufacturer* find(const qint32& id); + cManufacturer* find(const QString& name); + + bool fillList(QStandardItemModel* model); + + bool save(); +private: + cDatabase* m_db; + +signals: + void manufacturerAdded(cManufacturer* manufacturer); + void manufacturerRemoved(cManufacturer* manufacturer); +}; + +#endif // CMANUFACTURER_H diff --git a/cmanufacturerwindow.cpp b/cmanufacturerwindow.cpp new file mode 100644 index 0000000..0782a19 --- /dev/null +++ b/cmanufacturerwindow.cpp @@ -0,0 +1,111 @@ +#include "cmanufacturerwindow.h" +#include "ui_cmanufacturerwindow.h" + +#include "cmainwindow.h" + + +cManufacturerWindow::cManufacturerWindow(QWidget *parent) : + cMDISubWindow(parent), + ui(new Ui::cManufacturerWindow), + m_manufacturer(nullptr) +{ + ui->setupUi(this); +} + +cManufacturerWindow::~cManufacturerWindow() +{ + delete ui; +} + +void cManufacturerWindow::setManufacturer(cManufacturer* manufacturer) +{ + m_manufacturer = manufacturer; + + fillFields(); + + connect(ui->m_name, &QLineEdit::textChanged, this, &cManufacturerWindow::onNameChanged); + connect(ui->m_address, &QPlainTextEdit::textChanged, this, &cManufacturerWindow::onAddressChanged); + connect(ui->m_url, &QLineEdit::textChanged, this, &cManufacturerWindow::onURLChanged); + connect(ui->m_email, &QLineEdit::textChanged, this, &cManufacturerWindow::onEmailChanged); + connect(ui->m_phone, &QLineEdit::textChanged, this, &cManufacturerWindow::onPhoneChanged); + connect(ui->m_fax, &QLineEdit::textChanged, this, &cManufacturerWindow::onFaxChanged); + connect(ui->m_comment, &QPlainTextEdit::textChanged, this, &cManufacturerWindow::onCommentChanged); +} + +cManufacturer* cManufacturerWindow::manufacturer() +{ + return(m_manufacturer); +} + +void cManufacturerWindow::onManufacturerChanged(cManufacturer* manufacturer) +{ + if(m_manufacturer != manufacturer) + return; + + fillFields(); +} + +void cManufacturerWindow::onNameChanged(const QString& name) +{ + m_manufacturer->setName(name); + + if(m_manufacturer->item()) + m_manufacturer->item()->setText(name); + + emit somethingChanged(); +} + +void cManufacturerWindow::onAddressChanged() +{ + m_manufacturer->setAddress(ui->m_address->toPlainText()); + + emit somethingChanged(); +} + +void cManufacturerWindow::onURLChanged(const QString& url) +{ + m_manufacturer->setURL(url); + + emit somethingChanged(); +} + +void cManufacturerWindow::onEmailChanged(const QString& email) +{ + m_manufacturer->setEmail(email); + + emit somethingChanged(); +} + +void cManufacturerWindow::onPhoneChanged(const QString& phone) +{ + m_manufacturer->setPhone(phone); + + emit somethingChanged(); +} + +void cManufacturerWindow::onFaxChanged(const QString& fax) +{ + m_manufacturer->setFax(fax); + + emit somethingChanged(); +} + +void cManufacturerWindow::onCommentChanged() +{ + m_manufacturer->setComment(ui->m_comment->toPlainText()); + + emit somethingChanged(); +} + +void cManufacturerWindow::fillFields() +{ + ui->m_name->setText(m_manufacturer->name()); + ui->m_address->setPlainText(m_manufacturer->address()); + ui->m_url->setText(m_manufacturer->url()); + ui->m_email->setText(m_manufacturer->email()); + ui->m_phone->setText(m_manufacturer->phone()); + ui->m_fax->setText(m_manufacturer->fax()); + ui->m_comment->setPlainText(m_manufacturer->comment()); + + setWindowTitle("manufacturer - " + m_manufacturer->name()); +} diff --git a/cmanufacturerwindow.h b/cmanufacturerwindow.h new file mode 100644 index 0000000..68cab00 --- /dev/null +++ b/cmanufacturerwindow.h @@ -0,0 +1,50 @@ +#ifndef CMANUFACTURERWINDOW_H +#define CMANUFACTURERWINDOW_H + + +#include "cmanufacturer.h" + +#include "cmdisubwindow.h" +#include "cmainwindow.h" + +#include + + +namespace Ui { +class cManufacturerWindow; +} + +class cManufacturerWindow : public cMDISubWindow +{ + Q_OBJECT + +public: + explicit cManufacturerWindow(QWidget *parent = nullptr); + ~cManufacturerWindow(); + + void setManufacturer(cManufacturer* manufacturer); + cManufacturer* manufacturer(); + +private: + Ui::cManufacturerWindow* ui; + cManufacturer* m_manufacturer; + + void fillFields(); + +public slots: + void onManufacturerChanged(cManufacturer* manufacturer); + +private slots: + void onNameChanged(const QString& szName); + void onAddressChanged(); + void onURLChanged(const QString& szURL); + void onEmailChanged(const QString& szEmail); + void onPhoneChanged(const QString& szPhone); + void onFaxChanged(const QString& szFax); + void onCommentChanged(); + +signals: + void somethingChanged(); +}; + +#endif // CMANUFACTURERWINDOW_H diff --git a/cmanufacturerwindow.ui b/cmanufacturerwindow.ui new file mode 100644 index 0000000..3596786 --- /dev/null +++ b/cmanufacturerwindow.ui @@ -0,0 +1,95 @@ + + + cManufacturerWindow + + + + 0 + 0 + 400 + 300 + + + + Manufacturer - + + + + + + + + Name: + + + + + + + + + + Address: + + + + + + + + + + URL: + + + + + + + + + + Email: + + + + + + + + + + Phone: + + + + + + + + + + Fax: + + + + + + + + + + Comment: + + + + + + + + + + + + + diff --git a/cmdisubwindow.cpp b/cmdisubwindow.cpp new file mode 100644 index 0000000..7a9e47b --- /dev/null +++ b/cmdisubwindow.cpp @@ -0,0 +1,19 @@ +/*! + \file cmdisubwindow.cpp + +*/ + +#include "cmdisubwindow.h" + +#include + + +cMDISubWindow::cMDISubWindow(QWidget *parent) : QWidget(parent) +{ +} + +void cMDISubWindow::closeEvent(QCloseEvent* event) +{ + emit subWindowClosed(this); + event->accept(); +} diff --git a/cmdisubwindow.h b/cmdisubwindow.h new file mode 100644 index 0000000..ecd4d24 --- /dev/null +++ b/cmdisubwindow.h @@ -0,0 +1,51 @@ +/*! + \file cmdisubwindow.h + +*/ + +#ifndef CMDISUBWINDOW_H +#define CMDISUBWINDOW_H + + +#include + + +/*! + \brief + + \class cMDISubWindow cmdisubwindow.h "cmdisubwindow.h" +*/ +class cMDISubWindow : public QWidget +{ + Q_OBJECT +public: + /*! + \brief + + \fn cMDISubWindow + \param parent + */ + explicit cMDISubWindow(QWidget *parent = nullptr); + +signals: + /*! + \brief + + \fn subWindowClosed + \param lpWidget + */ + void subWindowClosed(QWidget* lpWidget); + +public slots: + +protected: + /*! + \brief + + \fn closeEvent + \param event + */ + void closeEvent(QCloseEvent *event); +}; + +#endif // CMDISUBWINDOW_H diff --git a/common.cpp b/common.cpp new file mode 100644 index 0000000..f027f9d --- /dev/null +++ b/common.cpp @@ -0,0 +1,12 @@ +/*! + \file common.cpp + +*/ + +/*! + \file common.cpp + +*/ + +#include "common.h" + diff --git a/common.h b/common.h new file mode 100644 index 0000000..22a7382 --- /dev/null +++ b/common.h @@ -0,0 +1,39 @@ +/*! + \file common.h + +*/ + +#ifndef COMMON_H +#define COMMON_H + + +#include + + +#define THUMBNAIL_WIDTH 160 +#define THUMBNAIL_HEIGHT 120 + + +#ifdef __GNUC__ + #define myDebug qDebug() << __FILE__ << "(" << __LINE__ << ") - " << __PRETTY_FUNCTION__ << ":" +#elif __MINGW32__ + #define myDebug qDebug() << __FILE__ << "(" << __LINE__ << ") - " << __PRETTY_FUNCTION__ << ":" +#else + #define myDebug qDebug() << __FILE__ << "(" << __LINE__ << ") - " << __FUNCTION__ << ":" +#endif + +#define ITEM_MANUFACTURER_DATA (Qt::UserRole+1) +#define ITEM_DISTRIBUTOR_DATA (Qt::UserRole+2) +#define ITEM_STORAGE_CATEGORY_DATA (Qt::UserRole+3) +#define ITEM_STORAGE_DATA (Qt::UserRole+4) +#define ITEM_PART_DATA (Qt::UserRole+5) +#define ITEM_PROJECT_DATA (Qt::UserRole+6) + +#define TAB_MANUFACTURER_LIST 1 +#define TAB_DISTRIBUTOR_LIST 2 +#define TAB_STORAGE_LIST 3 +#define TAB_PART_LIST 4 +#define TAB_PROJECT_LIST 5 + + +#endif // COMMON_H diff --git a/csplashscreen.cpp b/csplashscreen.cpp new file mode 100644 index 0000000..b8587a8 --- /dev/null +++ b/csplashscreen.cpp @@ -0,0 +1,68 @@ +/*! + \file csplashscreen.cpp + +*/ + +#include "csplashscreen.h" +//#include "common.h" + +#include + + +cSplashScreen::cSplashScreen(const QPixmap& pixmap, QFont& font) : + QSplashScreen(pixmap), + m_iMax(100), + m_iProgress(0) +{ + setFont(font); + m_textDocument.setDefaultFont(font); +} + +void cSplashScreen::setMax(qint32 max) +{ + m_iMax = max; +} + +void cSplashScreen::drawContents(QPainter *painter) +{ + painter->translate(m_rect.topLeft()); + m_textDocument.setHtml(m_szMessage); + m_textDocument.drawContents(painter); + + QStyleOptionProgressBar pbstyle; + pbstyle.initFrom(this); + pbstyle.state = QStyle::State_Enabled; + pbstyle.textVisible = false; + pbstyle.minimum = 0; + pbstyle.maximum = m_iMax; + pbstyle.progress = m_iProgress; + pbstyle.invertedAppearance = false; + pbstyle.rect = QRect(0, 330, 390, 10); // Where is it. + + // Draw it... + style()->drawControl(QStyle::CE_ProgressBar, &pbstyle, painter, this); +} + +void cSplashScreen::showStatusMessage(const QString& message) +{ + m_szMessage = message; + showMessage(m_szMessage); +} + +void cSplashScreen::addStatusMessage(const QString& message) +{ + m_szMessage.append(message); + showMessage(m_szMessage); +} + +void cSplashScreen::setMessageRect(QRect rect) +{ + m_rect = rect; + m_textDocument.setTextWidth(rect.width()); +} + +void cSplashScreen::setProgress(int value) +{ + m_iProgress = value; + update(); +} diff --git a/csplashscreen.h b/csplashscreen.h new file mode 100644 index 0000000..0ebe29b --- /dev/null +++ b/csplashscreen.h @@ -0,0 +1,78 @@ +/*! + \file csplashscreen.h + +*/ + +#ifndef CSPLASHSCREEN_H +#define CSPLASHSCREEN_H + + +#include +#include +#include + + +/*! + \brief + + \class cSplashScreen csplashscreen.h "csplashscreen.h" +*/ +class cSplashScreen : public QSplashScreen +{ +public: + cSplashScreen(const QPixmap& pixmap, QFont &font); + + /*! + \brief + + \fn drawContents + \param painter + */ + virtual void drawContents(QPainter *painter); + /*! + \brief + + \fn showStatusMessage + \param message + */ + void showStatusMessage(const QString &message); + /*! + \brief + + \fn addStatusMessage + \param message + */ + void addStatusMessage(const QString &message); + /*! + \brief + + \fn setMessageRect + \param rect + */ + void setMessageRect(QRect rect); + + /*! + \brief + + \fn setMax + \param max + */ + void setMax(qint32 max); + +private: + QTextDocument m_textDocument; /*!< TODO: describe */ + QString m_szMessage; /*!< TODO: describe */ + QRect m_rect; /*!< TODO: describe */ + qint32 m_iMax; /*!< TODO: describe */ + qint32 m_iProgress; /*!< TODO: describe */ +public slots: + /*! + \brief + + \fn setProgress + \param value + */ + void setProgress(int value); +}; + +#endif // CSPLASHSCREEN_H diff --git a/cstorage.cpp b/cstorage.cpp new file mode 100644 index 0000000..5d559af --- /dev/null +++ b/cstorage.cpp @@ -0,0 +1,325 @@ +#include "cstorage.h" + +#include +#include + +#include + +#include "common.h" + +#include + + +bool sortAsc(cStorage* &v1, cStorage* &v2) +{ + return(v1->name() < v2->name()); +} + + +cStorage::cStorage(cDatabase* db, qint32 id, QObject *parent) : + QObject(parent), + m_db(db), + m_changed(false), + m_id(id), + m_storageCategory(nullptr), + m_name(""), + m_description(""), + m_item(nullptr) +{ +} + +cStorage::cStorage(cStorage* storage) +{ + set(storage); +} + +void cStorage::set(cStorage* storage) +{ + m_db = storage->db(); + m_id = storage->id(); + m_storageCategory = storage->storageCategory(); + m_name = storage->name(); + m_description = storage->description(); +} + +void cStorage::setID(const qint32& id) +{ + m_id = id; + m_changed = true; + emit idChanged(id); + emit storageChanged(this); +} + +qint32 cStorage::id() +{ + return(m_id); +} + +void cStorage::setStorageCategory(cStorageCategory* storageCategory) +{ + m_storageCategory = storageCategory; + m_changed = true; + emit storageCategoryChanged(storageCategory); + emit storageChanged(this); +} + +cStorageCategory* cStorage::storageCategory() +{ + return(m_storageCategory); +} + +void cStorage::setName(const QString& name) +{ + m_name = name; + m_changed = true; + emit nameChanged(name); + emit storageChanged(this); +} + +QString cStorage::name() +{ + return(m_name); +} + +void cStorage::setDescription(const QString& description) +{ + m_description = description; + m_changed = true; + emit descriptionChanged(description); + emit storageChanged(this); +} + +QString cStorage::description() +{ + return(m_description); +} + +void cStorage::setItem(QStandardItem* item) +{ + m_item = item; +} + +QStandardItem* cStorage::item() +{ + return(m_item); +} + +bool cStorage::save() +{ + if(!m_changed) + return(true); + + QSqlQuery query; + + if(m_id == -1) + query.prepare("INSERT INTO storage (storageCategory, name, description) VALUES (:storageCategory, :name, :description);"); + else + query.prepare("UPDATE storage SET storageCategory=:storageCategory, name=:name, description=:description WHERE id=:id;"); + + query.bindValue(":id", m_id); + query.bindValue(":storageCategory", m_storageCategory->id()); + query.bindValue(":name", m_name); + query.bindValue(":description", m_description); + + if(!query.exec()) + { + myDebug << query.lastError().text(); + return(false); + } + + if(m_id == -1) + { + if(!query.exec("SELECT MAX(id) MAXID FROM storage;")) + { + myDebug << query.lastError().text(); + return(false); + } + + query.first(); + m_id = query.value("MAXID").toInt(); + } + m_changed = false; + return(true); +} + +void cStorage::clearSave() +{ + m_changed = false; +} + +bool cStorage::remove() +{ + QSqlQuery query; + + query.prepare("DELETE FROM storage WHERE id=:id;"); + query.bindValue(":id", m_id); + + if(!query.exec()) + { + myDebug << query.lastError().text(); + return(false); + } + + return(true); +} + +cDatabase* cStorage::db() +{ + return(m_db); +} + +cStorageList::cStorageList(cDatabase* db, cStorageCategoryList* storageCategoryList, QObject* parent) : + QObject(parent), + m_db(db), + m_storageCategoryList(storageCategoryList) +{ +} + +bool cStorageList::load() +{ + if(!m_db->db().isOpen()) + return(false); + + QString sql = QString("SELECT id, " + " storage_category_id, " + " name, " + " description " + "FROM storage " + "ORDER BY name, " + " id;"); + QSqlQuery query(m_db->db()); + + query.prepare(sql); + + if(!query.exec()) + { + myDebug << query.lastError().text(); + return(false); + } + + while(query.next()) + { + cStorage* lpStorage = new cStorage(m_db, query.value("id").toInt()); + cStorageCategory* storageCatgegory = m_storageCategoryList->find(query.value("storage_category_id").toInt()); + lpStorage->setStorageCategory(storageCatgegory); + lpStorage->setName(query.value("name").toString()); + lpStorage->setDescription(query.value("description").toString()); + storageCatgegory->addStorage(lpStorage); + + add(lpStorage); + } + + sort(); + + return(true); +} + +cStorage* cStorageList::add(const qint32& id) +{ + cStorage* lpNew = find(id); + + if(!lpNew) + { + lpNew = new cStorage(m_db, id); + append(lpNew); + emit storageAdded(lpNew); + } + + return(lpNew); +} + +cStorage* cStorageList::add(const QString& name) +{ + cStorage* lpNew = new cStorage(m_db); + lpNew->setName(name); + append(lpNew); + emit storageAdded(lpNew); + + return(lpNew); +} + +void cStorageList::add(cStorage* storage) +{ + append(storage); +} + +bool cStorageList::remove(const qint32& id) +{ + cStorage* storage = find(id); + if(!storage) + return(false); + + if(!storage->remove()) + return(false); + + if(!removeOne(storage)) + return(false); + + emit storageRemoved(storage); + + return(true); +} + +cStorage* cStorageList::find(const qint32& id) +{ + for(int i = 0;i < count();i++) + { + if(at(i)->id() == id) + return(at(i)); + } + + return(nullptr); +} + +cStorage* cStorageList::find(const QString& name) +{ + for(int i = 0;i < count();i++) + { + if(at(i)->name() == name) + return(at(i)); + } + + return(nullptr); +} + +void cStorageList::sort() +{ + std::sort(begin(), end(), sortAsc); +} + +bool cStorageList::fillList() +{ + if(!count()) + return(true); + + QStandardItem i; + QFont font = i.font(); + font.setItalic(true); + font.setBold(true); + + for(int i = 0;i < count();i++) + { + QStandardItem* item = new QStandardItem; + at(i)->setItem(item); + item->setText(at(i)->name()); + item->setData(QVariant::fromValue(at(i)), ITEM_STORAGE_DATA); + item->setFont(font); + + at(i)->storageCategory()->item()->appendRow(item); + } + + return(true); +} + +bool cStorageList::save() +{ + bool ret = true; + + for(int i = 0;i < count();i++) + { + if(!at(i)->save()) + ret = false; + } + + return(ret); +} diff --git a/cstorage.h b/cstorage.h new file mode 100644 index 0000000..3a00f98 --- /dev/null +++ b/cstorage.h @@ -0,0 +1,92 @@ +#ifndef CSTORAGE_H +#define CSTORAGE_H + + +#include "cdatabase.h" +#include "cstoragecategory.h" + +#include +#include +#include + +#include +#include + + +class cStorage : public QObject +{ + Q_OBJECT +public: + explicit cStorage(cDatabase* db, qint32 id = -1, QObject *parent = nullptr); + cStorage(cStorage* storage); + + void set(cStorage* storage); + + void setID(const qint32& id); + qint32 id(); + + void setStorageCategory(cStorageCategory* storageCategory); + cStorageCategory* storageCategory(); + + void setName(const QString& name); + QString name(); + + void setDescription(const QString& description); + QString description(); + + void setItem(QStandardItem* item); + QStandardItem* item(); + + bool save(); + void clearSave(); + bool remove(); + + cDatabase* db(); +private: + cDatabase* m_db; + bool m_changed; + qint32 m_id; + cStorageCategory* m_storageCategory; + QString m_name; + QString m_description; + QStandardItem* m_item; +signals: + void storageChanged(cStorage* storage); + void idChanged(const qint32& id); + void storageCategoryChanged(cStorageCategory* storageCategory); + void nameChanged(const QString& name); + void descriptionChanged(const QString& description); +}; + +Q_DECLARE_METATYPE(cStorage*) + +class cStorageList : public QObject, public QList +{ + Q_OBJECT + +public: + cStorageList(cDatabase* db, cStorageCategoryList* storageCategoryList, QObject* parent = nullptr); + + bool load(); + cStorage* add(const qint32& id); + cStorage* add(const QString& name); + void add(cStorage* storage); + bool remove(const qint32& id); + cStorage* find(const qint32& id); + cStorage* find(const QString& name); + + void sort(); + + bool fillList(); + + bool save(); +private: + cDatabase* m_db; + cStorageCategoryList* m_storageCategoryList; + +signals: + void storageAdded(cStorage* storage); + void storageRemoved(cStorage* storage); +}; + +#endif // CSTORAGE_H diff --git a/cstoragecategory.cpp b/cstoragecategory.cpp new file mode 100644 index 0000000..3874245 --- /dev/null +++ b/cstoragecategory.cpp @@ -0,0 +1,385 @@ +#include "cstoragecategory.h" +#include "cstorage.h" + +#include +#include + +#include + +#include "common.h" + +#include + + +bool sortAsc(cStorageCategory* &v1, cStorageCategory* &v2) +{ + return(v1->name() < v2->name()); +} + + +cStorageCategory::cStorageCategory(cDatabase* db, qint32 id, QObject* parent) : + QObject(parent), + m_db(db), + m_changed(false), + m_id(id), + m_parent(-1), + m_name(""), + m_description(""), + m_parentCategory(nullptr), + m_list(nullptr), + m_childList(new cStorageCategoryList(nullptr)), + m_storageList(new cStorageList(db, nullptr, nullptr)), + m_item(nullptr) +{ +} + +cStorageCategory::cStorageCategory(cStorageCategory* storageCategory) +{ + set(storageCategory); +} + +void cStorageCategory::set(cStorageCategory* storageCategory) +{ + m_db = storageCategory->db(); + m_id = storageCategory->id(); + m_parent = storageCategory->parent(); + m_name = storageCategory->name(); + m_description = storageCategory->description(); +} + +void cStorageCategory::setID(const qint32& id) +{ + m_id = id; + m_changed = true; + emit idChanged(id); + emit storageCategoryChanged(this); +} + +qint32 cStorageCategory::id() +{ + return(m_id); +} + +void cStorageCategory::setParent(const qint32& parent) +{ + m_parent = parent; + m_changed = true; + emit parentChanged(parent); + emit storageCategoryChanged(this); +} + +qint32 cStorageCategory::parent() +{ + return(m_parent); +} + +void cStorageCategory::addStorage(cStorage* storage) +{ + m_storageList->add(storage); +} + +cStorageList* cStorageCategory::storageList() +{ + return(m_storageList); +} + +void cStorageCategory::setName(const QString& name) +{ + m_name = name; + m_changed = true; + emit nameChanged(name); + emit storageCategoryChanged(this); +} + +QString cStorageCategory::name() +{ + return(m_name); +} + +void cStorageCategory::setDescription(const QString &description) +{ + m_description = description; + m_changed = true; + emit descriptionChanged(description); + emit storageCategoryChanged(this); +} + +QString cStorageCategory::description() +{ + return(m_description); +} + +void cStorageCategory::setParentCategory(cStorageCategory* parentCategory) +{ + m_parentCategory = parentCategory; +} + +cStorageCategory* cStorageCategory::parentCategory() +{ + return(m_parentCategory); +} + +void cStorageCategory::setItem(QStandardItem* item) +{ + m_item = item; +} + +QStandardItem* cStorageCategory::item() +{ + return(m_item); +} + +cStorageCategoryList* cStorageCategory::childList() +{ + return(m_childList); +} + +cDatabase* cStorageCategory::db() +{ + return(m_db); +} + +bool cStorageCategory::save() +{ + if(!m_changed) + return(true); + + QSqlQuery query; + + if(m_id == -1) + query.prepare("INSERT INTO storage_category (parent, name, description) VALUES (:parent, :name, :description);"); + else + query.prepare("UPDATE storage_category SET parent=:parent, name=:name, description=:description WHERE id=:id;"); + + query.bindValue(":id", m_id); + query.bindValue(":parent", (m_parent==-1)?QVariant(QVariant::Int):m_parent); + query.bindValue(":name", m_name); + query.bindValue(":description", m_description); + + if(!query.exec()) + { + myDebug << query.lastError().text(); + return(false); + } + + if(m_id == -1) + { + if(!query.exec("SELECT MAX(id) MAXID FROM storage_category;")) + { + myDebug << query.lastError().text(); + return(false); + } + + query.first(); + m_id = query.value("MAXID").toInt(); + } + m_changed = false; + return(true); +} + +bool cStorageCategory::remove() +{ + QSqlQuery query; + + query.prepare("DELETE FROM storage_category WHERE id=:id;"); + query.bindValue(":id", m_id); + + if(!query.exec()) + { + myDebug << query.lastError().text(); + return(false); + } + + return(true); +} + +void cStorageCategory::clearSave() +{ + m_changed = false; +} + +cStorageCategoryList::cStorageCategoryList(cDatabase* db, QObject* parent) : + QObject(parent), + m_db(db) +{ +} + +bool cStorageCategoryList::load() +{ + if(!m_db->db().isOpen()) + return(false); + + QString sql = QString("SELECT id, " + " parent, " + " name, " + " description " + "FROM storage_category " + "ORDER BY parent, " + " id;"); + QSqlQuery query(m_db->db()); + + query.prepare(sql); + + if(!query.exec()) + { + myDebug << query.lastError().text(); + return(false); + } + + while(query.next()) + { + cStorageCategory* lpCategory = new cStorageCategory(m_db, query.value("id").toInt()); + if(query.value("parent").isNull()) + lpCategory->setParent(-1); + else + lpCategory->setParent(query.value("parent").toInt()); + lpCategory->setName(query.value("name").toString()); + lpCategory->setDescription(query.value("description").toString()); + + cStorageCategory* lpParent = find(lpCategory->parent()); + + if(lpParent) + { + lpCategory->setParentCategory(lpParent); + lpParent->childList()->add(lpCategory); + } + else + add(lpCategory); + } + + sort(); + + return(true); +} + +cStorageCategory* cStorageCategoryList::add(const qint32& id) +{ + cStorageCategory* lpNew = find(id); + + if(!lpNew) + { + lpNew = new cStorageCategory(m_db, id); + append(lpNew); + emit storageCategoryAdded(lpNew); + } + + return(lpNew); +} + +cStorageCategory* cStorageCategoryList::add(const QString& name) +{ + cStorageCategory* lpNew = new cStorageCategory(m_db); + lpNew->setName(name); + append(lpNew); + emit storageCategoryAdded(lpNew); + + return(lpNew); +} + +void cStorageCategoryList::add(cStorageCategory* storageCategory) +{ + append(storageCategory); +} + +bool cStorageCategoryList::remove(const qint32& id) +{ + cStorageCategory* storageCategory = find(id); + if(!storageCategory) + return(false); + + if(!storageCategory->remove()) + return(false); + + if(!removeOne(storageCategory)) + return(false); + + emit storageCategoryRemoved(storageCategory); + + return(true); +} + +cStorageCategory* cStorageCategoryList::find(const qint32& id) +{ + for(int i = 0;i < count();i++) + { + if(at(i)->id() == id) + return(at(i)); + } + + cStorageCategory* category; + for(int i = 0;i < count();i++) + { + category = at(i)->childList()->find(id); + if(category) + return(category); + } + + return(nullptr); +} + +cStorageCategory* cStorageCategoryList::find(const QString& name) +{ + for(int i = 0;i < count();i++) + { + if(at(i)->name() == name) + return(at(i)); + } + + cStorageCategory* category; + for(int i = 0;i < count();i++) + { + category = at(i)->childList()->find(name); + if(category) + return(category); + } + + return(nullptr); +} + +void cStorageCategoryList::sort() +{ + std::sort(begin(), end(), sortAsc); + + for(int i = 0;i < count();i++) + at(i)->childList()->sort(); +} + +bool cStorageCategoryList::fillList(QStandardItemModel* model, QStandardItem* parent) +{ + if(!parent) + model->clear(); + + if(!count()) + return(true); + + for(int i = 0;i < count();i++) + { + QStandardItem* item = new QStandardItem; + at(i)->setItem(item); + item->setText(at(i)->name()); + item->setData(QVariant::fromValue(at(i)), ITEM_STORAGE_CATEGORY_DATA); + + if(parent) + parent->appendRow(item); + else + model->appendRow(item); + + if(at(i)->childList()) + at(i)->childList()->fillList(model, item); + } + + return(true); +} + +bool cStorageCategoryList::save() +{ + bool ret = true; + + for(int i = 0;i < count();i++) + { + if(!at(i)->save()) + ret = false; + } + + return(ret); +} diff --git a/cstoragecategory.h b/cstoragecategory.h new file mode 100644 index 0000000..faa1bba --- /dev/null +++ b/cstoragecategory.h @@ -0,0 +1,109 @@ +#ifndef CSTORAGECATEGORY_H +#define CSTORAGECATEGORY_H + + +#include "cdatabase.h" + +#include +#include +#include + +#include +#include + + +class cStorageCategoryList; +class cStorage; +class cStorageList; + +class cStorageCategory : public QObject +{ + Q_OBJECT +public: + explicit cStorageCategory(cDatabase* db, qint32 id = -1, QObject *parent = nullptr); + cStorageCategory(cStorageCategory* storageCategory); + + void set(cStorageCategory* storageCategory); + + void setID(const qint32& id); + qint32 id(); + + void setParent(const qint32& parent); + qint32 parent(); + + void setName(const QString& name); + QString name(); + + void setDescription(const QString& description); + QString description(); + + void setParentCategory(cStorageCategory* parentCategory); + cStorageCategory* parentCategory(); + + void addStorage(cStorage* storage); + cStorageList* storageList(); + + void setItem(QStandardItem* item); + QStandardItem* item(); + + bool save(); + void clearSave(); + bool remove(); + + void setList(cStorageCategoryList* list); + cStorageCategoryList* list(); + + cStorageCategoryList* childList(); + + cDatabase* db(); +private: + cDatabase* m_db; + bool m_changed; + qint32 m_id; + qint32 m_parent; + QString m_name; + QString m_description; + cStorageCategory* m_parentCategory; + cStorageCategoryList* m_list; + cStorageCategoryList* m_childList; + cStorageList* m_storageList; + QStandardItem* m_item; +signals: + void storageCategoryChanged(cStorageCategory* storageCategory); + void idChanged(const qint32& id); + void parentChanged(const qint32& parent); + void nameChanged(const QString& name); + void descriptionChanged(const QString& description); +}; + +Q_DECLARE_METATYPE(cStorageCategory*) + +class cStorageCategoryList : public QObject, public QList +{ + Q_OBJECT + +public: + cStorageCategoryList(cDatabase* db, QObject* parent = nullptr); + + bool load(); + cStorageCategory* add(const qint32& id); + cStorageCategory* add(const QString& name); + void add(cStorageCategory* storageCategory); + bool remove(const qint32& id); + cStorageCategory* find(const qint32& id); + cStorageCategory* find(const QString& name); + + void sort(); + + bool fillList(QStandardItemModel* model, QStandardItem* parent = 0); + + bool save(); +private: + cDatabase* m_db; + +signals: + void storageCategoryAdded(cStorageCategory* storageCategory); + void storageCategoryRemoved(cStorageCategory* storageCategory); +}; + +#endif // CSTORAGECATEGORY_H diff --git a/cwidget.cpp b/cwidget.cpp new file mode 100644 index 0000000..575a2e3 --- /dev/null +++ b/cwidget.cpp @@ -0,0 +1,51 @@ +/*! + \file cwidget.cpp + +*/ + +#include "cwidget.h" + + +cWidget::cWidget(cManufacturerWindow* parent) : + QWidget(parent), + m_type(TYPE_manufacturer), + m_lpWidget(parent), + m_lpWindow(0) +{ +} + +cWidget::cWidget(cDistributorWindow* parent) : + QWidget(parent), + m_type(TYPE_distributor), + m_lpWidget(parent), + m_lpWindow(0) +{ +} + +cWidget::cWidget(QWidget* parent) : + QWidget(parent), + m_type(TYPE_unknown), + m_lpWidget(parent), + m_lpWindow(0) +{ +} + +void cWidget::setWindow(QMdiSubWindow* lpWindow) +{ + m_lpWindow = lpWindow; +} + +QMdiSubWindow* cWidget::window() +{ + return(m_lpWindow); +} + +QWidget* cWidget::widget() +{ + return(m_lpWidget); +} + +cWidget::TYPE cWidget::type() +{ + return(m_type); +} diff --git a/cwidget.h b/cwidget.h new file mode 100644 index 0000000..9f01903 --- /dev/null +++ b/cwidget.h @@ -0,0 +1,55 @@ +#ifndef CWIDGET_H +#define CWIDGET_H + + +#include "cmanufacturerwindow.h" +#include "cdistributorwindow.h" + +#include +#include + + +/*! + \brief + + \class cWidget cwidget.h "cwidget.h" +*/ +class cWidget : public QWidget +{ + Q_OBJECT +public: + /*! + \brief + + \enum TYPE + */ + enum TYPE + { + TYPE_unknown = 0, + TYPE_manufacturer = 1, + TYPE_distributor = 2, + TYPE_storage = 3, + TYPE_part = 4, + TYPE_project = 5, + }; + + explicit cWidget(cManufacturerWindow* parent); + explicit cWidget(cDistributorWindow* parent); + explicit cWidget(QWidget* parent); + + QWidget* widget(); + + void setWindow(QMdiSubWindow* lpWindow); + QMdiSubWindow* window(); + TYPE type(); +signals: + +public slots: + +private: + TYPE m_type; + QWidget* m_lpWidget; + QMdiSubWindow* m_lpWindow; +}; + +#endif // CWIDGET_H diff --git a/images/splashEmpty.png b/images/splashEmpty.png new file mode 100644 index 0000000..5329d63 Binary files /dev/null and b/images/splashEmpty.png differ diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..268eaa5 --- /dev/null +++ b/main.cpp @@ -0,0 +1,41 @@ +#include "cmainwindow.h" + +#include +#include + +#include "csplashscreen.h" + + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + + a.setApplicationVersion(APP_VERSION); + a.setApplicationDisplayName("partlistManager"); + a.setOrganizationName("WIN-DESIGN"); + a.setOrganizationDomain("windesign.at"); + a.setApplicationName("partlistManager"); + + QSettings settings; + + QPixmap pixmap(":/images/splash.png"); + QFont splashFont; + cSplashScreen* lpSplash = new cSplashScreen(pixmap, splashFont); + + lpSplash->show(); + a.processEvents(); + + lpSplash->showStatusMessage(QObject::tr("
initializing...")); + + cMainWindow w(lpSplash); + + if(settings.value("main/maximized").toBool()) + w.showMaximized(); + else + w.show(); + + lpSplash->finish(&w); + delete lpSplash; + + return a.exec(); +} diff --git a/partlistManager.pro b/partlistManager.pro new file mode 100644 index 0000000..ade6911 --- /dev/null +++ b/partlistManager.pro @@ -0,0 +1,77 @@ +VERSION = "0.0.1.0" + +QMAKE_TARGET_COMPANY = "WIN-DESIGN" +QMAKE_TARGET_PRODUCT = "partlistManager" +QMAKE_TARGET_DESCRIPTION = "partlistManager" +QMAKE_TARGET_COPYRIGHT = "(c) 2019 WIN-DESIGN" +QMAKE_TARGET_DOMAIN = "windesign.at" + +QT += core gui sql + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +win32-msvc* { + contains(QT_ARCH, i386) { + message("msvc 32-bit") + } else { + message("msvc 64-bit") + } +} + +win32-g++ { + message("mingw") +} + +unix { + message("*nix") +} + +CONFIG += c++11 + +# You can make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +DEFINES += APP_VERSION=\\\"$$VERSION\\\" + +SOURCES += \ + cdatabase.cpp \ + cdistributor.cpp \ + cdistributorwindow.cpp \ + cmanufacturer.cpp \ + cmanufacturerwindow.cpp \ + cmdisubwindow.cpp \ + common.cpp \ + csplashscreen.cpp \ + cstorage.cpp \ + cstoragecategory.cpp \ + cwidget.cpp \ + main.cpp \ + cmainwindow.cpp + +HEADERS += \ + cdatabase.h \ + cdistributor.h \ + cdistributorwindow.h \ + cmainwindow.h \ + cmanufacturer.h \ + cmanufacturerwindow.h \ + cmdisubwindow.h \ + common.h \ + csplashscreen.h \ + cstorage.h \ + cstoragecategory.h \ + cwidget.h + +FORMS += \ + cdistributorwindow.ui \ + cmainwindow.ui \ + cmanufacturerwindow.ui + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +RESOURCES += \ + partlistmanager.qrc diff --git a/partlistmanager.qrc b/partlistmanager.qrc new file mode 100644 index 0000000..e77931b --- /dev/null +++ b/partlistmanager.qrc @@ -0,0 +1,659 @@ + + + images/splashEmpty.png + + + themes/tango/16x16/actions/address-book-new.png + themes/tango/16x16/actions/appointment-new.png + themes/tango/16x16/actions/bookmark-new.png + themes/tango/16x16/actions/contact-new.png + themes/tango/16x16/actions/document-new.png + themes/tango/16x16/actions/document-open.png + themes/tango/16x16/actions/document-print-preview.png + themes/tango/16x16/actions/document-print.png + themes/tango/16x16/actions/document-pdf.png + themes/tango/16x16/actions/document-properties.png + themes/tango/16x16/actions/document-revert.png + themes/tango/16x16/actions/document-save-as.png + themes/tango/16x16/actions/document-save.png + themes/tango/16x16/actions/edit-clear.png + themes/tango/16x16/actions/edit-copy.png + themes/tango/16x16/actions/edit-cut.png + themes/tango/16x16/actions/edit-delete.png + themes/tango/16x16/actions/edit-find-replace.png + themes/tango/16x16/actions/edit-find.png + themes/tango/16x16/actions/edit-paste.png + themes/tango/16x16/actions/edit-redo.png + themes/tango/16x16/actions/edit-select-all.png + themes/tango/16x16/actions/edit-undo.png + themes/tango/16x16/actions/folder-new.png + themes/tango/16x16/actions/format-indent-less.png + themes/tango/16x16/actions/format-indent-more.png + themes/tango/16x16/actions/format-justify-center.png + themes/tango/16x16/actions/format-justify-fill.png + themes/tango/16x16/actions/format-justify-left.png + themes/tango/16x16/actions/format-justify-right.png + themes/tango/16x16/actions/format-text-bold.png + themes/tango/16x16/actions/format-text-italic.png + themes/tango/16x16/actions/format-text-strikethrough.png + themes/tango/16x16/actions/format-text-underline.png + themes/tango/16x16/actions/go-bottom.png + themes/tango/16x16/actions/go-down.png + themes/tango/16x16/actions/go-first.png + themes/tango/16x16/actions/go-home.png + themes/tango/16x16/actions/go-jump.png + themes/tango/16x16/actions/go-last.png + themes/tango/16x16/actions/go-next.png + themes/tango/16x16/actions/go-previous.png + themes/tango/16x16/actions/go-top.png + themes/tango/16x16/actions/go-up.png + themes/tango/16x16/actions/list-add.png + themes/tango/16x16/actions/list-remove.png + themes/tango/16x16/actions/mail-forward.png + themes/tango/16x16/actions/mail-mark-junk.png + themes/tango/16x16/actions/mail-mark-not-junk.png + themes/tango/16x16/actions/mail-message-new.png + themes/tango/16x16/actions/mail-reply-all.png + themes/tango/16x16/actions/mail-reply-sender.png + themes/tango/16x16/actions/mail-send-receive.png + themes/tango/16x16/actions/media-eject.png + themes/tango/16x16/actions/media-playback-pause.png + themes/tango/16x16/actions/media-playback-start.png + themes/tango/16x16/actions/media-playback-stop.png + themes/tango/16x16/actions/media-record.png + themes/tango/16x16/actions/media-seek-backward.png + themes/tango/16x16/actions/media-seek-forward.png + themes/tango/16x16/actions/media-skip-backward.png + themes/tango/16x16/actions/media-skip-forward.png + themes/tango/16x16/actions/process-stop.png + themes/tango/16x16/actions/system-lock-screen.png + themes/tango/16x16/actions/system-log-out.png + themes/tango/16x16/actions/system-search.png + themes/tango/16x16/actions/system-shutdown.png + themes/tango/16x16/actions/tab-new.png + themes/tango/16x16/actions/view-fullscreen.png + themes/tango/16x16/actions/view-refresh.png + themes/tango/16x16/actions/window-new.png + themes/tango/16x16/animations/process-working.png + themes/tango/16x16/apps/accessories-calculator.png + themes/tango/16x16/apps/accessories-character-map.png + themes/tango/16x16/apps/accessories-text-editor.png + themes/tango/16x16/apps/help-browser.png + themes/tango/16x16/apps/internet-group-chat.png + themes/tango/16x16/apps/internet-mail.png + themes/tango/16x16/apps/internet-news-reader.png + themes/tango/16x16/apps/internet-web-browser.png + themes/tango/16x16/apps/office-calendar.png + themes/tango/16x16/apps/preferences-desktop-accessibility.png + themes/tango/16x16/apps/preferences-desktop-assistive-technology.png + themes/tango/16x16/apps/preferences-desktop-font.png + themes/tango/16x16/apps/preferences-desktop-keyboard-shortcuts.png + themes/tango/16x16/apps/preferences-desktop-locale.png + themes/tango/16x16/apps/preferences-desktop-multimedia.png + themes/tango/16x16/apps/preferences-desktop-remote-desktop.png + themes/tango/16x16/apps/preferences-desktop-screensaver.png + themes/tango/16x16/apps/preferences-desktop-theme.png + themes/tango/16x16/apps/preferences-desktop-wallpaper.png + themes/tango/16x16/apps/preferences-system-network-proxy.png + themes/tango/16x16/apps/preferences-system-session.png + themes/tango/16x16/apps/preferences-system-windows.png + themes/tango/16x16/apps/system-file-manager.png + themes/tango/16x16/apps/system-installer.png + themes/tango/16x16/apps/system-software-update.png + themes/tango/16x16/apps/system-users.png + themes/tango/16x16/apps/utilities-system-monitor.png + themes/tango/16x16/apps/utilities-terminal.png + themes/tango/16x16/categories/applications-accessories.png + themes/tango/16x16/categories/applications-development.png + themes/tango/16x16/categories/applications-games.png + themes/tango/16x16/categories/applications-graphics.png + themes/tango/16x16/categories/applications-internet.png + themes/tango/16x16/categories/applications-multimedia.png + themes/tango/16x16/categories/applications-office.png + themes/tango/16x16/categories/applications-other.png + themes/tango/16x16/categories/applications-system.png + themes/tango/16x16/categories/preferences-desktop-peripherals.png + themes/tango/16x16/categories/preferences-desktop.png + themes/tango/16x16/categories/preferences-system.png + themes/tango/16x16/devices/audio-card.png + themes/tango/16x16/devices/audio-input-microphone.png + themes/tango/16x16/devices/battery.png + themes/tango/16x16/devices/camera-photo.png + themes/tango/16x16/devices/camera-video.png + themes/tango/16x16/devices/computer.png + themes/tango/16x16/devices/drive-harddisk.png + themes/tango/16x16/devices/drive-optical.png + themes/tango/16x16/devices/drive-removable-media.png + themes/tango/16x16/devices/input-gaming.png + themes/tango/16x16/devices/input-keyboard.png + themes/tango/16x16/devices/input-mouse.png + themes/tango/16x16/devices/media-flash.png + themes/tango/16x16/devices/media-floppy.png + themes/tango/16x16/devices/media-optical.png + themes/tango/16x16/devices/multimedia-player.png + themes/tango/16x16/devices/network-wired.png + themes/tango/16x16/devices/network-wireless.png + themes/tango/16x16/devices/printer.png + themes/tango/16x16/devices/video-display.png + themes/tango/16x16/emblems/emblem-favorite.png + themes/tango/16x16/emblems/emblem-important.png + themes/tango/16x16/emblems/emblem-photos.png + themes/tango/16x16/emblems/emblem-readonly.png + themes/tango/16x16/emblems/emblem-symbolic-link.png + themes/tango/16x16/emblems/emblem-system.png + themes/tango/16x16/emblems/emblem-unreadable.png + themes/tango/16x16/emotes/face-angel.png + themes/tango/16x16/emotes/face-crying.png + themes/tango/16x16/emotes/face-devilish.png + themes/tango/16x16/emotes/face-glasses.png + themes/tango/16x16/emotes/face-grin.png + themes/tango/16x16/emotes/face-kiss.png + themes/tango/16x16/emotes/face-monkey.png + themes/tango/16x16/emotes/face-plain.png + themes/tango/16x16/emotes/face-sad.png + themes/tango/16x16/emotes/face-smile-big.png + themes/tango/16x16/emotes/face-smile.png + themes/tango/16x16/emotes/face-surprise.png + themes/tango/16x16/emotes/face-wink.png + themes/tango/16x16/mimetypes/application-certificate.png + themes/tango/16x16/mimetypes/application-x-executable.png + themes/tango/16x16/mimetypes/audio-x-generic.png + themes/tango/16x16/mimetypes/font-x-generic.png + themes/tango/16x16/mimetypes/image-x-generic.png + themes/tango/16x16/mimetypes/package-x-generic.png + themes/tango/16x16/mimetypes/text-html.png + themes/tango/16x16/mimetypes/text-x-generic-template.png + themes/tango/16x16/mimetypes/text-x-generic.png + themes/tango/16x16/mimetypes/text-x-script.png + themes/tango/16x16/mimetypes/video-x-generic.png + themes/tango/16x16/mimetypes/x-office-address-book.png + themes/tango/16x16/mimetypes/x-office-calendar.png + themes/tango/16x16/mimetypes/x-office-document-template.png + themes/tango/16x16/mimetypes/x-office-document.png + themes/tango/16x16/mimetypes/x-office-drawing-template.png + themes/tango/16x16/mimetypes/x-office-drawing.png + themes/tango/16x16/mimetypes/x-office-presentation-template.png + themes/tango/16x16/mimetypes/x-office-presentation.png + themes/tango/16x16/mimetypes/x-office-spreadsheet-template.png + themes/tango/16x16/mimetypes/x-office-spreadsheet.png + themes/tango/16x16/places/folder-remote.png + themes/tango/16x16/places/folder-saved-search.png + themes/tango/16x16/places/folder.png + themes/tango/16x16/places/network-server.png + themes/tango/16x16/places/network-workgroup.png + themes/tango/16x16/places/start-here.png + themes/tango/16x16/places/user-desktop.png + themes/tango/16x16/places/user-home.png + themes/tango/16x16/places/user-trash.png + themes/tango/16x16/status/audio-volume-high.png + themes/tango/16x16/status/audio-volume-low.png + themes/tango/16x16/status/audio-volume-medium.png + themes/tango/16x16/status/audio-volume-muted.png + themes/tango/16x16/status/battery-caution.png + themes/tango/16x16/status/dialog-error.png + themes/tango/16x16/status/dialog-information.png + themes/tango/16x16/status/dialog-warning.png + themes/tango/16x16/status/folder-drag-accept.png + themes/tango/16x16/status/folder-open.png + themes/tango/16x16/status/folder-visiting.png + themes/tango/16x16/status/image-loading.png + themes/tango/16x16/status/image-missing.png + themes/tango/16x16/status/mail-attachment.png + themes/tango/16x16/status/network-error.png + themes/tango/16x16/status/network-idle.png + themes/tango/16x16/status/network-offline.png + themes/tango/16x16/status/network-receive.png + themes/tango/16x16/status/network-transmit-receive.png + themes/tango/16x16/status/network-transmit.png + themes/tango/16x16/status/network-wireless-encrypted.png + themes/tango/16x16/status/printer-error.png + themes/tango/16x16/status/software-update-available.png + themes/tango/16x16/status/software-update-urgent.png + themes/tango/16x16/status/user-trash-full.png + themes/tango/16x16/status/weather-clear-night.png + themes/tango/16x16/status/weather-clear.png + themes/tango/16x16/status/weather-few-clouds-night.png + themes/tango/16x16/status/weather-few-clouds.png + themes/tango/16x16/status/weather-overcast.png + themes/tango/16x16/status/weather-severe-alert.png + themes/tango/16x16/status/weather-showers-scattered.png + themes/tango/16x16/status/weather-showers.png + themes/tango/16x16/status/weather-snow.png + themes/tango/16x16/status/weather-storm.png + themes/tango/22x22/actions/address-book-new.png + themes/tango/22x22/actions/appointment-new.png + themes/tango/22x22/actions/bookmark-new.png + themes/tango/22x22/actions/contact-new.png + themes/tango/22x22/actions/document-new.png + themes/tango/22x22/actions/document-open.png + themes/tango/22x22/actions/document-print-preview.png + themes/tango/22x22/actions/document-print.png + themes/tango/22x22/actions/document-pdf.png + themes/tango/22x22/actions/document-properties.png + themes/tango/22x22/actions/document-revert.png + themes/tango/22x22/actions/document-save-as.png + themes/tango/22x22/actions/document-save.png + themes/tango/22x22/actions/edit-clear.png + themes/tango/22x22/actions/edit-copy.png + themes/tango/22x22/actions/edit-cut.png + themes/tango/22x22/actions/edit-delete.png + themes/tango/22x22/actions/edit-find-replace.png + themes/tango/22x22/actions/edit-find.png + themes/tango/22x22/actions/edit-paste.png + themes/tango/22x22/actions/edit-redo.png + themes/tango/22x22/actions/edit-select-all.png + themes/tango/22x22/actions/edit-undo.png + themes/tango/22x22/actions/folder-new.png + themes/tango/22x22/actions/format-indent-less.png + themes/tango/22x22/actions/format-indent-more.png + themes/tango/22x22/actions/format-justify-center.png + themes/tango/22x22/actions/format-justify-fill.png + themes/tango/22x22/actions/format-justify-left.png + themes/tango/22x22/actions/format-justify-right.png + themes/tango/22x22/actions/format-text-bold.png + themes/tango/22x22/actions/format-text-italic.png + themes/tango/22x22/actions/format-text-strikethrough.png + themes/tango/22x22/actions/format-text-underline.png + themes/tango/22x22/actions/go-bottom.png + themes/tango/22x22/actions/go-down.png + themes/tango/22x22/actions/go-first.png + themes/tango/22x22/actions/go-home.png + themes/tango/22x22/actions/go-jump.png + themes/tango/22x22/actions/go-last.png + themes/tango/22x22/actions/go-next.png + themes/tango/22x22/actions/go-previous.png + themes/tango/22x22/actions/go-top.png + themes/tango/22x22/actions/go-up.png + themes/tango/22x22/actions/list-add.png + themes/tango/22x22/actions/list-remove.png + themes/tango/22x22/actions/mail-forward.png + themes/tango/22x22/actions/mail-mark-junk.png + themes/tango/22x22/actions/mail-mark-not-junk.png + themes/tango/22x22/actions/mail-message-new.png + themes/tango/22x22/actions/mail-reply-all.png + themes/tango/22x22/actions/mail-reply-sender.png + themes/tango/22x22/actions/mail-send-receive.png + themes/tango/22x22/actions/media-eject.png + themes/tango/22x22/actions/media-playback-pause.png + themes/tango/22x22/actions/media-playback-start.png + themes/tango/22x22/actions/media-playback-stop.png + themes/tango/22x22/actions/media-record.png + themes/tango/22x22/actions/media-seek-backward.png + themes/tango/22x22/actions/media-seek-forward.png + themes/tango/22x22/actions/media-skip-backward.png + themes/tango/22x22/actions/media-skip-forward.png + themes/tango/22x22/actions/process-stop.png + themes/tango/22x22/actions/system-lock-screen.png + themes/tango/22x22/actions/system-log-out.png + themes/tango/22x22/actions/system-search.png + themes/tango/22x22/actions/system-shutdown.png + themes/tango/22x22/actions/tab-new.png + themes/tango/22x22/actions/view-fullscreen.png + themes/tango/22x22/actions/view-refresh.png + themes/tango/22x22/actions/window-new.png + themes/tango/22x22/animations/process-working.png + themes/tango/22x22/apps/accessories-calculator.png + themes/tango/22x22/apps/accessories-character-map.png + themes/tango/22x22/apps/accessories-text-editor.png + themes/tango/22x22/apps/help-browser.png + themes/tango/22x22/apps/internet-group-chat.png + themes/tango/22x22/apps/internet-mail.png + themes/tango/22x22/apps/internet-news-reader.png + themes/tango/22x22/apps/internet-web-browser.png + themes/tango/22x22/apps/office-calendar.png + themes/tango/22x22/apps/preferences-desktop-accessibility.png + themes/tango/22x22/apps/preferences-desktop-assistive-technology.png + themes/tango/22x22/apps/preferences-desktop-font.png + themes/tango/22x22/apps/preferences-desktop-keyboard-shortcuts.png + themes/tango/22x22/apps/preferences-desktop-locale.png + themes/tango/22x22/apps/preferences-desktop-multimedia.png + themes/tango/22x22/apps/preferences-desktop-remote-desktop.png + themes/tango/22x22/apps/preferences-desktop-screensaver.png + themes/tango/22x22/apps/preferences-desktop-theme.png + themes/tango/22x22/apps/preferences-desktop-wallpaper.png + themes/tango/22x22/apps/preferences-system-network-proxy.png + themes/tango/22x22/apps/preferences-system-session.png + themes/tango/22x22/apps/preferences-system-windows.png + themes/tango/22x22/apps/system-file-manager.png + themes/tango/22x22/apps/system-installer.png + themes/tango/22x22/apps/system-software-update.png + themes/tango/22x22/apps/system-users.png + themes/tango/22x22/apps/utilities-system-monitor.png + themes/tango/22x22/apps/utilities-terminal.png + themes/tango/22x22/categories/applications-accessories.png + themes/tango/22x22/categories/applications-development.png + themes/tango/22x22/categories/applications-games.png + themes/tango/22x22/categories/applications-graphics.png + themes/tango/22x22/categories/applications-internet.png + themes/tango/22x22/categories/applications-multimedia.png + themes/tango/22x22/categories/applications-office.png + themes/tango/22x22/categories/applications-other.png + themes/tango/22x22/categories/applications-system.png + themes/tango/22x22/categories/preferences-desktop-peripherals.png + themes/tango/22x22/categories/preferences-desktop.png + themes/tango/22x22/categories/preferences-system.png + themes/tango/22x22/devices/audio-card.png + themes/tango/22x22/devices/audio-input-microphone.png + themes/tango/22x22/devices/battery.png + themes/tango/22x22/devices/camera-photo.png + themes/tango/22x22/devices/camera-video.png + themes/tango/22x22/devices/computer.png + themes/tango/22x22/devices/drive-harddisk.png + themes/tango/22x22/devices/drive-optical.png + themes/tango/22x22/devices/drive-removable-media.png + themes/tango/22x22/devices/input-gaming.png + themes/tango/22x22/devices/input-keyboard.png + themes/tango/22x22/devices/input-mouse.png + themes/tango/22x22/devices/media-flash.png + themes/tango/22x22/devices/media-floppy.png + themes/tango/22x22/devices/media-optical.png + themes/tango/22x22/devices/multimedia-player.png + themes/tango/22x22/devices/network-wired.png + themes/tango/22x22/devices/network-wireless.png + themes/tango/22x22/devices/printer.png + themes/tango/22x22/devices/video-display.png + themes/tango/22x22/emblems/emblem-favorite.png + themes/tango/22x22/emblems/emblem-important.png + themes/tango/22x22/emblems/emblem-photos.png + themes/tango/22x22/emblems/emblem-readonly.png + themes/tango/22x22/emblems/emblem-symbolic-link.png + themes/tango/22x22/emblems/emblem-system.png + themes/tango/22x22/emblems/emblem-unreadable.png + themes/tango/22x22/emotes/face-angel.png + themes/tango/22x22/emotes/face-crying.png + themes/tango/22x22/emotes/face-devilish.png + themes/tango/22x22/emotes/face-glasses.png + themes/tango/22x22/emotes/face-grin.png + themes/tango/22x22/emotes/face-kiss.png + themes/tango/22x22/emotes/face-monkey.png + themes/tango/22x22/emotes/face-plain.png + themes/tango/22x22/emotes/face-sad.png + themes/tango/22x22/emotes/face-smile-big.png + themes/tango/22x22/emotes/face-smile.png + themes/tango/22x22/emotes/face-surprise.png + themes/tango/22x22/emotes/face-wink.png + themes/tango/22x22/mimetypes/application-certificate.png + themes/tango/22x22/mimetypes/application-x-executable.png + themes/tango/22x22/mimetypes/audio-x-generic.png + themes/tango/22x22/mimetypes/font-x-generic.png + themes/tango/22x22/mimetypes/image-x-generic.png + themes/tango/22x22/mimetypes/package-x-generic.png + themes/tango/22x22/mimetypes/text-html.png + themes/tango/22x22/mimetypes/text-x-generic-template.png + themes/tango/22x22/mimetypes/text-x-generic.png + themes/tango/22x22/mimetypes/text-x-script.png + themes/tango/22x22/mimetypes/video-x-generic.png + themes/tango/22x22/mimetypes/x-office-address-book.png + themes/tango/22x22/mimetypes/x-office-calendar.png + themes/tango/22x22/mimetypes/x-office-document-template.png + themes/tango/22x22/mimetypes/x-office-document.png + themes/tango/22x22/mimetypes/x-office-drawing-template.png + themes/tango/22x22/mimetypes/x-office-drawing.png + themes/tango/22x22/mimetypes/x-office-presentation-template.png + themes/tango/22x22/mimetypes/x-office-presentation.png + themes/tango/22x22/mimetypes/x-office-spreadsheet-template.png + themes/tango/22x22/mimetypes/x-office-spreadsheet.png + themes/tango/22x22/places/folder-remote.png + themes/tango/22x22/places/folder-saved-search.png + themes/tango/22x22/places/folder.png + themes/tango/22x22/places/network-server.png + themes/tango/22x22/places/network-workgroup.png + themes/tango/22x22/places/start-here.png + themes/tango/22x22/places/user-desktop.png + themes/tango/22x22/places/user-home.png + themes/tango/22x22/places/user-trash.png + themes/tango/22x22/status/audio-volume-high.png + themes/tango/22x22/status/audio-volume-low.png + themes/tango/22x22/status/audio-volume-medium.png + themes/tango/22x22/status/audio-volume-muted.png + themes/tango/22x22/status/battery-caution.png + themes/tango/22x22/status/dialog-error.png + themes/tango/22x22/status/dialog-information.png + themes/tango/22x22/status/dialog-warning.png + themes/tango/22x22/status/folder-drag-accept.png + themes/tango/22x22/status/folder-open.png + themes/tango/22x22/status/folder-visiting.png + themes/tango/22x22/status/image-loading.png + themes/tango/22x22/status/image-missing.png + themes/tango/22x22/status/mail-attachment.png + themes/tango/22x22/status/network-error.png + themes/tango/22x22/status/network-idle.png + themes/tango/22x22/status/network-offline.png + themes/tango/22x22/status/network-receive.png + themes/tango/22x22/status/network-transmit-receive.png + themes/tango/22x22/status/network-transmit.png + themes/tango/22x22/status/network-wireless-encrypted.png + themes/tango/22x22/status/printer-error.png + themes/tango/22x22/status/software-update-available.png + themes/tango/22x22/status/software-update-urgent.png + themes/tango/22x22/status/user-trash-full.png + themes/tango/22x22/status/weather-clear-night.png + themes/tango/22x22/status/weather-clear.png + themes/tango/22x22/status/weather-few-clouds-night.png + themes/tango/22x22/status/weather-few-clouds.png + themes/tango/22x22/status/weather-overcast.png + themes/tango/22x22/status/weather-severe-alert.png + themes/tango/22x22/status/weather-showers-scattered.png + themes/tango/22x22/status/weather-showers.png + themes/tango/22x22/status/weather-snow.png + themes/tango/22x22/status/weather-storm.png + themes/tango/32x32/actions/address-book-new.png + themes/tango/32x32/actions/appointment-new.png + themes/tango/32x32/actions/bookmark-new.png + themes/tango/32x32/actions/contact-new.png + themes/tango/32x32/actions/document-new.png + themes/tango/32x32/actions/document-open.png + themes/tango/32x32/actions/document-print-preview.png + themes/tango/32x32/actions/document-print.png + themes/tango/32x32/actions/document-pdf.png + themes/tango/32x32/actions/document-properties.png + themes/tango/32x32/actions/document-revert.png + themes/tango/32x32/actions/document-save-as.png + themes/tango/32x32/actions/document-save.png + themes/tango/32x32/actions/edit-clear.png + themes/tango/32x32/actions/edit-copy.png + themes/tango/32x32/actions/edit-cut.png + themes/tango/32x32/actions/edit-delete.png + themes/tango/32x32/actions/edit-find-replace.png + themes/tango/32x32/actions/edit-find.png + themes/tango/32x32/actions/edit-paste.png + themes/tango/32x32/actions/edit-redo.png + themes/tango/32x32/actions/edit-select-all.png + themes/tango/32x32/actions/edit-undo.png + themes/tango/32x32/actions/folder-new.png + themes/tango/32x32/actions/format-indent-less.png + themes/tango/32x32/actions/format-indent-more.png + themes/tango/32x32/actions/format-justify-center.png + themes/tango/32x32/actions/format-justify-fill.png + themes/tango/32x32/actions/format-justify-left.png + themes/tango/32x32/actions/format-justify-right.png + themes/tango/32x32/actions/format-text-bold.png + themes/tango/32x32/actions/format-text-italic.png + themes/tango/32x32/actions/format-text-strikethrough.png + themes/tango/32x32/actions/format-text-underline.png + themes/tango/32x32/actions/go-bottom.png + themes/tango/32x32/actions/go-down.png + themes/tango/32x32/actions/go-first.png + themes/tango/32x32/actions/go-home.png + themes/tango/32x32/actions/go-jump.png + themes/tango/32x32/actions/go-last.png + themes/tango/32x32/actions/go-next.png + themes/tango/32x32/actions/go-previous.png + themes/tango/32x32/actions/go-top.png + themes/tango/32x32/actions/go-up.png + themes/tango/32x32/actions/list-add.png + themes/tango/32x32/actions/list-remove.png + themes/tango/32x32/actions/mail-forward.png + themes/tango/32x32/actions/mail-mark-junk.png + themes/tango/32x32/actions/mail-mark-not-junk.png + themes/tango/32x32/actions/mail-message-new.png + themes/tango/32x32/actions/mail-reply-all.png + themes/tango/32x32/actions/mail-reply-sender.png + themes/tango/32x32/actions/mail-send-receive.png + themes/tango/32x32/actions/media-eject.png + themes/tango/32x32/actions/media-playback-pause.png + themes/tango/32x32/actions/media-playback-start.png + themes/tango/32x32/actions/media-playback-stop.png + themes/tango/32x32/actions/media-record.png + themes/tango/32x32/actions/media-seek-backward.png + themes/tango/32x32/actions/media-seek-forward.png + themes/tango/32x32/actions/media-skip-backward.png + themes/tango/32x32/actions/media-skip-forward.png + themes/tango/32x32/actions/process-stop.png + themes/tango/32x32/actions/system-lock-screen.png + themes/tango/32x32/actions/system-log-out.png + themes/tango/32x32/actions/system-search.png + themes/tango/32x32/actions/system-shutdown.png + themes/tango/32x32/actions/tab-new.png + themes/tango/32x32/actions/view-fullscreen.png + themes/tango/32x32/actions/view-refresh.png + themes/tango/32x32/actions/window-new.png + themes/tango/32x32/animations/process-working.png + themes/tango/32x32/apps/accessories-calculator.png + themes/tango/32x32/apps/accessories-character-map.png + themes/tango/32x32/apps/accessories-text-editor.png + themes/tango/32x32/apps/help-browser.png + themes/tango/32x32/apps/internet-group-chat.png + themes/tango/32x32/apps/internet-mail.png + themes/tango/32x32/apps/internet-news-reader.png + themes/tango/32x32/apps/internet-web-browser.png + themes/tango/32x32/apps/office-calendar.png + themes/tango/32x32/apps/preferences-desktop-accessibility.png + themes/tango/32x32/apps/preferences-desktop-assistive-technology.png + themes/tango/32x32/apps/preferences-desktop-font.png + themes/tango/32x32/apps/preferences-desktop-keyboard-shortcuts.png + themes/tango/32x32/apps/preferences-desktop-locale.png + themes/tango/32x32/apps/preferences-desktop-multimedia.png + themes/tango/32x32/apps/preferences-desktop-remote-desktop.png + themes/tango/32x32/apps/preferences-desktop-screensaver.png + themes/tango/32x32/apps/preferences-desktop-theme.png + themes/tango/32x32/apps/preferences-desktop-wallpaper.png + themes/tango/32x32/apps/preferences-system-network-proxy.png + themes/tango/32x32/apps/preferences-system-session.png + themes/tango/32x32/apps/preferences-system-windows.png + themes/tango/32x32/apps/system-file-manager.png + themes/tango/32x32/apps/system-installer.png + themes/tango/32x32/apps/system-software-update.png + themes/tango/32x32/apps/system-users.png + themes/tango/32x32/apps/utilities-system-monitor.png + themes/tango/32x32/apps/utilities-terminal.png + themes/tango/32x32/categories/applications-accessories.png + themes/tango/32x32/categories/applications-development.png + themes/tango/32x32/categories/applications-games.png + themes/tango/32x32/categories/applications-graphics.png + themes/tango/32x32/categories/applications-internet.png + themes/tango/32x32/categories/applications-multimedia.png + themes/tango/32x32/categories/applications-office.png + themes/tango/32x32/categories/applications-other.png + themes/tango/32x32/categories/applications-system.png + themes/tango/32x32/categories/preferences-desktop-peripherals.png + themes/tango/32x32/categories/preferences-desktop.png + themes/tango/32x32/categories/preferences-system.png + themes/tango/32x32/devices/audio-card.png + themes/tango/32x32/devices/audio-input-microphone.png + themes/tango/32x32/devices/battery.png + themes/tango/32x32/devices/camera-photo.png + themes/tango/32x32/devices/camera-video.png + themes/tango/32x32/devices/computer.png + themes/tango/32x32/devices/drive-harddisk.png + themes/tango/32x32/devices/drive-optical.png + themes/tango/32x32/devices/drive-removable-media.png + themes/tango/32x32/devices/input-gaming.png + themes/tango/32x32/devices/input-keyboard.png + themes/tango/32x32/devices/input-mouse.png + themes/tango/32x32/devices/media-flash.png + themes/tango/32x32/devices/media-floppy.png + themes/tango/32x32/devices/media-optical.png + themes/tango/32x32/devices/multimedia-player.png + themes/tango/32x32/devices/network-wired.png + themes/tango/32x32/devices/network-wireless.png + themes/tango/32x32/devices/printer.png + themes/tango/32x32/devices/video-display.png + themes/tango/32x32/emblems/emblem-favorite.png + themes/tango/32x32/emblems/emblem-important.png + themes/tango/32x32/emblems/emblem-photos.png + themes/tango/32x32/emblems/emblem-readonly.png + themes/tango/32x32/emblems/emblem-symbolic-link.png + themes/tango/32x32/emblems/emblem-system.png + themes/tango/32x32/emblems/emblem-unreadable.png + themes/tango/32x32/emotes/face-angel.png + themes/tango/32x32/emotes/face-crying.png + themes/tango/32x32/emotes/face-devilish.png + themes/tango/32x32/emotes/face-glasses.png + themes/tango/32x32/emotes/face-grin.png + themes/tango/32x32/emotes/face-kiss.png + themes/tango/32x32/emotes/face-monkey.png + themes/tango/32x32/emotes/face-plain.png + themes/tango/32x32/emotes/face-sad.png + themes/tango/32x32/emotes/face-smile-big.png + themes/tango/32x32/emotes/face-smile.png + themes/tango/32x32/emotes/face-surprise.png + themes/tango/32x32/emotes/face-wink.png + themes/tango/32x32/mimetypes/application-certificate.png + themes/tango/32x32/mimetypes/application-x-executable.png + themes/tango/32x32/mimetypes/audio-x-generic.png + themes/tango/32x32/mimetypes/font-x-generic.png + themes/tango/32x32/mimetypes/image-x-generic.png + themes/tango/32x32/mimetypes/package-x-generic.png + themes/tango/32x32/mimetypes/text-html.png + themes/tango/32x32/mimetypes/text-x-generic-template.png + themes/tango/32x32/mimetypes/text-x-generic.png + themes/tango/32x32/mimetypes/text-x-script.png + themes/tango/32x32/mimetypes/video-x-generic.png + themes/tango/32x32/mimetypes/x-office-address-book.png + themes/tango/32x32/mimetypes/x-office-calendar.png + themes/tango/32x32/mimetypes/x-office-document-template.png + themes/tango/32x32/mimetypes/x-office-document.png + themes/tango/32x32/mimetypes/x-office-drawing-template.png + themes/tango/32x32/mimetypes/x-office-drawing.png + themes/tango/32x32/mimetypes/x-office-presentation-template.png + themes/tango/32x32/mimetypes/x-office-presentation.png + themes/tango/32x32/mimetypes/x-office-spreadsheet-template.png + themes/tango/32x32/mimetypes/x-office-spreadsheet.png + themes/tango/32x32/places/folder-remote.png + themes/tango/32x32/places/folder-saved-search.png + themes/tango/32x32/places/folder.png + themes/tango/32x32/places/network-server.png + themes/tango/32x32/places/network-workgroup.png + themes/tango/32x32/places/start-here.png + themes/tango/32x32/places/user-desktop.png + themes/tango/32x32/places/user-home.png + themes/tango/32x32/places/user-trash.png + themes/tango/32x32/status/audio-volume-high.png + themes/tango/32x32/status/audio-volume-low.png + themes/tango/32x32/status/audio-volume-medium.png + themes/tango/32x32/status/audio-volume-muted.png + themes/tango/32x32/status/battery-caution.png + themes/tango/32x32/status/dialog-error.png + themes/tango/32x32/status/dialog-information.png + themes/tango/32x32/status/dialog-warning.png + themes/tango/32x32/status/folder-drag-accept.png + themes/tango/32x32/status/folder-open.png + themes/tango/32x32/status/folder-visiting.png + themes/tango/32x32/status/image-loading.png + themes/tango/32x32/status/image-missing.png + themes/tango/32x32/status/mail-attachment.png + themes/tango/32x32/status/network-error.png + themes/tango/32x32/status/network-idle.png + themes/tango/32x32/status/network-offline.png + themes/tango/32x32/status/network-receive.png + themes/tango/32x32/status/network-transmit-receive.png + themes/tango/32x32/status/network-transmit.png + themes/tango/32x32/status/network-wireless-encrypted.png + themes/tango/32x32/status/printer-error.png + themes/tango/32x32/status/software-update-available.png + themes/tango/32x32/status/software-update-urgent.png + themes/tango/32x32/status/user-trash-full.png + themes/tango/32x32/status/weather-clear-night.png + themes/tango/32x32/status/weather-clear.png + themes/tango/32x32/status/weather-few-clouds-night.png + themes/tango/32x32/status/weather-few-clouds.png + themes/tango/32x32/status/weather-overcast.png + themes/tango/32x32/status/weather-severe-alert.png + themes/tango/32x32/status/weather-showers-scattered.png + themes/tango/32x32/status/weather-showers.png + themes/tango/32x32/status/weather-snow.png + themes/tango/32x32/status/weather-storm.png + themes/tango/index.theme + + diff --git a/partlistsmanager.qrc b/partlistsmanager.qrc new file mode 100644 index 0000000..fb32232 --- /dev/null +++ b/partlistsmanager.qrc @@ -0,0 +1,8 @@ + + + images/splashEmpty.png + + + themes/tango/index.theme + +