261 lines
7.4 KiB
C
261 lines
7.4 KiB
C
|
#ifndef CUSTOM_FILE_DIALOG_H
|
||
|
#define CUSTOM_FILE_DIALOG_H
|
||
|
|
||
|
#include <QFileDialog>
|
||
|
#include <QLineEdit>
|
||
|
#include <QPushButton>
|
||
|
#include <QListWidget>
|
||
|
#include <QLayout>
|
||
|
#include <QButtonGroup>
|
||
|
#include <string>
|
||
|
|
||
|
#define USE_FILE_DLG_WITHOUT_PROMPT
|
||
|
|
||
|
template<class T>
|
||
|
class custom_file_dlg
|
||
|
{
|
||
|
QLineEdit* edit_;
|
||
|
QLineEdit* new_;
|
||
|
QPushButton *save_;
|
||
|
QFileDialog *fdlg_;
|
||
|
QListView *list_;
|
||
|
|
||
|
enum find_cls
|
||
|
{
|
||
|
FIND_BUTTON = 1,
|
||
|
FIND_LINE_EDIT,
|
||
|
FIND_LIST,
|
||
|
};
|
||
|
typedef struct _find_ctrl
|
||
|
{
|
||
|
int cls;
|
||
|
std::string title;
|
||
|
QObject *found;
|
||
|
}FINDCTRL, *LPFINDCTRL;
|
||
|
|
||
|
static bool find_ctrls(QObject* obj, LPFINDCTRL ret)
|
||
|
{
|
||
|
if(ret->cls == FIND_BUTTON)
|
||
|
{
|
||
|
QPushButton* btn = dynamic_cast<QPushButton*>(obj);
|
||
|
if(btn)
|
||
|
{
|
||
|
std::string t(btn->text().toStdString());
|
||
|
if(ret->title.empty() || t == ret->title) // "\344\277\235\345\255\230(&S)")
|
||
|
{
|
||
|
ret->found = obj;
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
QButtonGroup* grp = dynamic_cast<QButtonGroup*>(obj);
|
||
|
if(grp)
|
||
|
{
|
||
|
printf("Found button-group with %d buttons\n", grp->buttons().size());
|
||
|
QList<QAbstractButton*> btns = grp->buttons();
|
||
|
for(auto& b : btns)
|
||
|
{
|
||
|
btn = dynamic_cast<QPushButton*>(b);
|
||
|
if(btn)
|
||
|
{
|
||
|
std::string t(btn->text().toStdString());
|
||
|
if(ret->title.empty() || t == ret->title) // "\344\277\235\345\255\230(&S)")
|
||
|
{
|
||
|
ret->found = obj;
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if(ret->cls == FIND_LINE_EDIT)
|
||
|
{
|
||
|
QLineEdit* edit = dynamic_cast<QLineEdit*>(obj);
|
||
|
if(edit)
|
||
|
{
|
||
|
std::string t(edit->text().toStdString());
|
||
|
if(ret->title.empty() || t == ret->title) // "\344\277\235\345\255\230(&S)")
|
||
|
{
|
||
|
ret->found = obj;
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else if(ret->cls == FIND_LIST)
|
||
|
{
|
||
|
QListView *v = dynamic_cast<QListView*>(obj);
|
||
|
if(v)
|
||
|
{
|
||
|
std::string t(v->objectName().toStdString());
|
||
|
if(ret->title.empty() && ret->title.empty()) // || t == ret->title)
|
||
|
{
|
||
|
ret->found = obj;
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
QListWidget *l = dynamic_cast<QListWidget*>(obj);
|
||
|
if(l)
|
||
|
{
|
||
|
printf("Found list widget\n");
|
||
|
}
|
||
|
else {
|
||
|
QListView *v = dynamic_cast<QListView*>(obj);
|
||
|
if(v)
|
||
|
printf("Found list view: %s\n", v->objectName().toStdString().c_str());
|
||
|
}
|
||
|
QObjectList objs(obj->children());
|
||
|
for(auto& o : objs)
|
||
|
{
|
||
|
if(find_ctrls(o, ret))
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
QPushButton* save_button(void){return save_;}
|
||
|
QLineEdit* input_edit(bool org){return org ? edit_ : new_;}
|
||
|
QListView* file_list(void){return list_;}
|
||
|
void replace_input(QLineEdit* from, QLineEdit* tobe)
|
||
|
{
|
||
|
fdlg_->layout()->replaceWidget(from, tobe);
|
||
|
from->hide();
|
||
|
tobe->show();
|
||
|
}
|
||
|
|
||
|
protected slots:
|
||
|
virtual void on_file_dialog_textChanged(const QString &path) = 0;
|
||
|
virtual void on_file_dialog_returnPressed() = 0;
|
||
|
|
||
|
protected:
|
||
|
custom_file_dlg() : edit_(nullptr), new_(nullptr), save_(nullptr), fdlg_(nullptr), list_(nullptr)
|
||
|
{
|
||
|
}
|
||
|
~custom_file_dlg()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
public:
|
||
|
static QLineEdit* find_input_box(QFileDialog* host)
|
||
|
{
|
||
|
FINDCTRL fc;
|
||
|
QObjectList objs(host->children());
|
||
|
|
||
|
fc.cls = FIND_LINE_EDIT;
|
||
|
fc.found = nullptr;
|
||
|
for(auto& o : objs)
|
||
|
{
|
||
|
QString objName = o->objectName();
|
||
|
if(custom_file_dlg::find_ctrls(o, &fc))
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return dynamic_cast<QLineEdit*>(fc.found);
|
||
|
}
|
||
|
static QPushButton* find_button(QFileDialog* host, const char* title)
|
||
|
{
|
||
|
FINDCTRL fc;
|
||
|
QObjectList objs(host->children());
|
||
|
|
||
|
fc.cls = FIND_BUTTON;
|
||
|
fc.title = (title && *title) ? title : "";
|
||
|
fc.found = nullptr;
|
||
|
for(auto& o : objs)
|
||
|
{
|
||
|
QString objName = o->objectName();
|
||
|
if(custom_file_dlg::find_ctrls(o, &fc))
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return dynamic_cast<QPushButton*>(fc.found);
|
||
|
}
|
||
|
static QListView* find_list(QFileDialog* host, const char* title)
|
||
|
{
|
||
|
FINDCTRL fc;
|
||
|
QObjectList objs(host->children());
|
||
|
|
||
|
fc.cls = FIND_LIST;
|
||
|
fc.title = (title && *title) ? title : "";
|
||
|
fc.found = nullptr;
|
||
|
for(auto& o : objs)
|
||
|
{
|
||
|
if(custom_file_dlg::find_ctrls(o, &fc))
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return dynamic_cast<QListView*>(fc.found);
|
||
|
}
|
||
|
|
||
|
|
||
|
protected:
|
||
|
bool init_custom_file_dlg(QFileDialog* fdlg)
|
||
|
{
|
||
|
new_ = new QLineEdit(((T*)this));
|
||
|
fdlg_ = fdlg;
|
||
|
edit_ = custom_file_dlg::find_input_box(fdlg);
|
||
|
save_ = custom_file_dlg::find_button(fdlg, QObject::tr("&Save").toStdString().c_str());
|
||
|
list_ = custom_file_dlg::find_list(fdlg, "");
|
||
|
if(edit_ && save_ && list_)
|
||
|
{
|
||
|
enable_prompt(false);
|
||
|
((T*)this)->connect(new_, SIGNAL(textChanged(const QString&)), (T*)this, SLOT(on_file_dialog_textChanged(const QString)));
|
||
|
((T*)this)->connect(new_, SIGNAL(returnPressed()), (T*)this, SLOT(on_file_dialog_returnPressed()));
|
||
|
((T*)this)->connect(fdlg, SIGNAL(currentChanged(const QString&)), (T*)this, SLOT(on_file_dialog_textChanged(const QString)));
|
||
|
fdlg->setFocus();
|
||
|
new_->setFocus();
|
||
|
}
|
||
|
return edit_ && save_;
|
||
|
}
|
||
|
void enable_prompt(bool enable)
|
||
|
{
|
||
|
if(edit_)
|
||
|
{
|
||
|
if(enable)
|
||
|
replace_input(new_, edit_);
|
||
|
else
|
||
|
replace_input(edit_, new_);
|
||
|
}
|
||
|
}
|
||
|
void on_file_name_changed(const QLineEdit* ctrl, const QString& text)
|
||
|
{
|
||
|
if(ctrl == nullptr) // send by QFileDialog
|
||
|
{
|
||
|
std::string name(text.toStdString());
|
||
|
size_t pos = name.rfind('/');
|
||
|
if(pos++ != std::string::npos)
|
||
|
name.erase(0, pos);
|
||
|
new_->setText(QString::fromStdString(name));
|
||
|
}
|
||
|
else if(ctrl == edit_ && new_)
|
||
|
new_->setText(text);
|
||
|
else if(edit_)
|
||
|
{
|
||
|
QString ext(text), sel_ext(((T*)this)->getSaveExt());
|
||
|
int pos = ext.lastIndexOf('.');
|
||
|
|
||
|
list_->clearSelection();
|
||
|
if(pos == -1)
|
||
|
edit_->setText(text + sel_ext);
|
||
|
else {
|
||
|
ext = ext.right(ext.length() - pos);
|
||
|
if(ext.compare(sel_ext, Qt::CaseInsensitive) == 0)
|
||
|
edit_->setText(text);
|
||
|
else
|
||
|
edit_->setText(text + sel_ext);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(save_)
|
||
|
save_->setEnabled(!text.isEmpty());
|
||
|
}
|
||
|
void on_file_name_press_return(void)
|
||
|
{
|
||
|
emit save_->clicked();
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
#endif // CUSTOM_FILE_DIALOG_H
|