diff --git a/src/Gui/BitmapFactory.cpp b/src/Gui/BitmapFactory.cpp index fea73c064f..4879aba908 100644 --- a/src/Gui/BitmapFactory.cpp +++ b/src/Gui/BitmapFactory.cpp @@ -114,16 +114,6 @@ BitmapFactoryInst::~BitmapFactoryInst() delete d; } -void BitmapFactoryInst::addCustomPath(const QString& path) -{ - Base::Reference group = App::GetApplication().GetParameterGroupByPath - ("User parameter:BaseApp/Preferences/Bitmaps"); - std::vector paths = group->GetASCIIs("CustomPath"); - std::stringstream str; - str << "CustomPath" << paths.size(); - group->SetASCII(str.str().c_str(), (const char*)path.toUtf8()); -} - void BitmapFactoryInst::restoreCustomPaths() { Base::Reference group = App::GetApplication().GetParameterGroupByPath @@ -145,6 +135,11 @@ void BitmapFactoryInst::removePath(const QString& path) if (pos != -1) d->paths.removeAt(pos); } +QStringList BitmapFactoryInst::getPaths() const +{ + return d->paths; +} + QStringList BitmapFactoryInst::findIconFiles() const { QStringList files, filters; diff --git a/src/Gui/BitmapFactory.h b/src/Gui/BitmapFactory.h index 4579c7b741..478585d309 100644 --- a/src/Gui/BitmapFactory.h +++ b/src/Gui/BitmapFactory.h @@ -54,12 +54,12 @@ public: static BitmapFactoryInst& instance(void); static void destruct (void); - void addCustomPath(const QString&); - /// Adds a path where pixmaps can be found void addPath(const QString& path); /// Removes a path from the list of pixmap paths void removePath(const QString& path); + /// Returns the list of search paths + QStringList getPaths() const; /// Returns the absolute file names of icons found in the given search paths QStringList findIconFiles() const; /// Adds a build in XPM pixmap under a given name diff --git a/src/Gui/DlgActionsImp.cpp b/src/Gui/DlgActionsImp.cpp index 1783e10d86..b439672a20 100644 --- a/src/Gui/DlgActionsImp.cpp +++ b/src/Gui/DlgActionsImp.cpp @@ -23,14 +23,17 @@ #include "PreCompiled.h" #ifndef _PreComp_ +# include # include # include # include # include # include # include +# include # include # include +# include #endif #include "DlgActionsImp.h" @@ -422,26 +425,53 @@ void IconDialog::resizeEvent(QResizeEvent*) void IconDialog::onAddIconPath() { - QString dir = QFileDialog::getExistingDirectory(this, IconDialog::tr("Add icon"), QString()); - if (!dir.isEmpty()) { - QStringList filters; - QList formats = QImageReader::supportedImageFormats(); - for (QList::iterator it = formats.begin(); it != formats.end(); ++it) - filters << QString::fromAscii("*.%1").arg(QString::fromAscii(*it).toLower()); - QDir d(dir); - d.setNameFilters(filters); - QFileInfoList fi = d.entryInfoList(); - for (QFileInfoList::iterator it = fi.begin(); it != fi.end(); ++it) { - QListWidgetItem* item; - QString file = it->absoluteFilePath(); - item = new QListWidgetItem(ui->listWidget); - item->setIcon(QIcon(file)); - item->setText(it->baseName()); - item->setToolTip(file); + // Add the user defined paths + Base::Reference group = App::GetApplication().GetParameterGroupByPath + ("User parameter:BaseApp/Preferences/Bitmaps"); + std::vector paths = group->GetASCIIs("CustomPath"); + QStringList pathList; + for (std::vector::iterator it = paths.begin(); it != paths.end(); ++it) + pathList << QString::fromUtf8(it->c_str()); + + IconFolders dlg(pathList, this); + dlg.setWindowTitle(tr("Icon folders")); + if (dlg.exec()) { + QStringList paths = dlg.getPaths(); + + // Write to user config + group->Clear(); + int index=0; + for (QStringList::iterator it = paths.begin(); it != paths.end(); ++it, ++index) { + std::stringstream str; + str << "CustomPath" << index; + group->SetASCII(str.str().c_str(), (const char*)it->toUtf8()); } - BitmapFactory().addPath(dir); - BitmapFactory().addCustomPath(dir); + QStringList search = BitmapFactory().getPaths(); + for (QStringList::iterator it = search.begin(); it != search.end(); ++it) { + *it = QDir::toNativeSeparators(*it); + } + for (QStringList::iterator it = paths.begin(); it != paths.end(); ++it) { + if (search.indexOf(*it) < 0) { + QStringList filters; + QList formats = QImageReader::supportedImageFormats(); + for (QList::iterator jt = formats.begin(); jt != formats.end(); ++jt) + filters << QString::fromAscii("*.%1").arg(QString::fromAscii(*jt).toLower()); + QDir d(*it); + d.setNameFilters(filters); + QFileInfoList fi = d.entryInfoList(); + for (QFileInfoList::iterator jt = fi.begin(); jt != fi.end(); ++jt) { + QListWidgetItem* item; + QString file = jt->absoluteFilePath(); + item = new QListWidgetItem(ui->listWidget); + item->setIcon(QIcon(file)); + item->setText(jt->baseName()); + item->setToolTip(file); + } + + BitmapFactory().addPath(*it); + } + } } } @@ -502,5 +532,137 @@ void DlgCustomActionsImp::changeEvent(QEvent *e) QWidget::changeEvent(e); } +IconFolders::IconFolders(const QStringList& paths, QWidget* parent) + : QDialog(parent), restart(false), maxLines(10) +{ + resize(600,400); + QDialogButtonBox* buttonBox = new QDialogButtonBox(this); + buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + connect(buttonBox, SIGNAL(accepted()), + this, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), + this, SLOT(reject())); + + gridLayout = new QGridLayout(); + QGridLayout* mainLayout = new QGridLayout(this); + mainLayout->addLayout(gridLayout, 0, 0, 1, 1); + + QSpacerItem* verticalSpacer = new QSpacerItem(20, 108, QSizePolicy::Minimum, QSizePolicy::Expanding); + mainLayout->addItem(verticalSpacer, 1, 0, 1, 1); + mainLayout->addWidget(buttonBox, 2, 0, 1, 1); + + // Add the user defined paths + int numPaths = static_cast(paths.size()); + int maxRow = this->maxLines; + for (int row=0; rowsetReadOnly(true); + gridLayout->addWidget(edit, row, 0, 1, 1); + QPushButton* removeButton = new QPushButton(this); + removeButton->setIcon(BitmapFactory().pixmap("edit_remove")); + gridLayout->addWidget(removeButton, row, 1, 1, 1); + + if (row < numPaths) { + edit->setText(paths[row]); + } + else { + edit->hide(); + removeButton->hide(); + } + + buttonMap.append(qMakePair(edit, removeButton)); + connect(removeButton, SIGNAL(clicked()), this, SLOT(removeFolder())); + } + + textLabel = new QLabel(this); + textLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); + textLabel->setText(tr("Add or remove custom icon folders")); + addButton = new QPushButton(this); + addButton->setIcon(BitmapFactory().pixmap("add")); + gridLayout->addWidget(textLabel, maxRow, 0, 1, 1); + gridLayout->addWidget(addButton, maxRow, 1, 1, 1); + + connect(addButton, SIGNAL(clicked()), this, SLOT(addFolder())); + if (numPaths >= this->maxLines) + addButton->setDisabled(true); +} + +IconFolders::~IconFolders() +{ +} + +void IconFolders::addFolder() +{ + int countHidden = -1; + QStringList paths; + for (QList< QPair >::iterator it = buttonMap.begin(); it != buttonMap.end(); ++it) { + if (it->first->isHidden()) { + countHidden++; + if (countHidden == 0) { + QString dir = QFileDialog::getExistingDirectory(this, IconDialog::tr("Add icon folder"), QString()); + if (!dir.isEmpty() && paths.indexOf(dir) < 0) { + QLineEdit* edit = it->first; + edit->setVisible(true); + edit->setText(dir); + QPushButton* removeButton = it->second; + removeButton->setVisible(true); + } + } + } + else { + paths << QDir::toNativeSeparators(it->first->text()); + } + } + + if (countHidden <= 0) { + addButton->setDisabled(true); + } +} + +void IconFolders::removeFolder() +{ + if (!restart) { + restart = true; + QMessageBox::information(this, tr("Remove folder"), + tr("Removing a folder only takes effect after an application restart.")); + } + + addButton->setEnabled(true); + QPushButton* remove = static_cast(sender()); + QLineEdit* edit = 0; + for (QList< QPair >::iterator it = buttonMap.begin(); it != buttonMap.end(); ++it) { + if (it->second == remove) { + edit = it->first; + } + else if (edit) { + // move up the text of the line edits + edit->setText(it->first->text()); + + if (it->first->isVisible()) { + edit = it->first; + remove = it->second; + } + else { + edit->hide(); + remove->hide(); + break; + } + } + } +} + +QStringList IconFolders::getPaths() const +{ + QStringList paths; + for (QList< QPair >::const_iterator it = buttonMap.begin(); it != buttonMap.end(); ++it) { + if (!it->first->isHidden()) { + paths << QDir::toNativeSeparators(it->first->text()); + } + else { + break; + } + } + return paths; +} #include "moc_DlgActionsImp.cpp" diff --git a/src/Gui/DlgActionsImp.h b/src/Gui/DlgActionsImp.h index 37a3c15337..e402533fdb 100644 --- a/src/Gui/DlgActionsImp.h +++ b/src/Gui/DlgActionsImp.h @@ -27,6 +27,8 @@ #include "ui_DlgActions.h" #include "PropertyPage.h" #include +#include +#include namespace Gui { @@ -102,6 +104,28 @@ private: Ui_DlgChooseIcon *ui; }; +class IconFolders : public QDialog +{ + Q_OBJECT + +public: + IconFolders(const QStringList&, QWidget* parent); + ~IconFolders(); + QStringList getPaths() const; + +private Q_SLOTS: + void addFolder(); + void removeFolder(); + +private: + bool restart; + int maxLines; + QGridLayout* gridLayout; + QLabel* textLabel; + QPushButton* addButton; + QList< QPair > buttonMap; +}; + } // namespace Dialog } // namespace Gui diff --git a/src/Gui/DlgChooseIcon.ui b/src/Gui/DlgChooseIcon.ui index 567bd4cc0a..c2b569d7e2 100644 --- a/src/Gui/DlgChooseIcon.ui +++ b/src/Gui/DlgChooseIcon.ui @@ -35,7 +35,7 @@ - Add icons... + Icon folders...