diff --git a/src/frontends/controllers/ChangeLog b/src/frontends/controllers/ChangeLog index ae17a736fa..ffd2cc4c7a 100644 --- a/src/frontends/controllers/ChangeLog +++ b/src/frontends/controllers/ChangeLog @@ -1,3 +1,9 @@ +2005-05-13 Angus Leeming + + * helper_funcs.C (browseFile, browseDir): remove the loop that tested + whether the returned file name is valid in order to break out of the + loop. + 2005-05-08 Angus Leeming * Kernel.h (KernelDocType): wrapper class for the Kernel::DocTypes diff --git a/src/frontends/controllers/helper_funcs.C b/src/frontends/controllers/helper_funcs.C index aafd5f3537..582d88820f 100644 --- a/src/frontends/controllers/helper_funcs.C +++ b/src/frontends/controllers/helper_funcs.C @@ -16,10 +16,10 @@ #include "gettext.h" -#include "frontends/Alert.h" #include "frontends/FileDialog.h" #include "support/filetools.h" +#include "support/lstrings.h" #include "support/package.h" using std::pair; @@ -61,27 +61,12 @@ string const browseFile(string const & filename, FileDialog::Result result; - while (true) { - if (save) - result = fileDlg.save(lastPath, filters, - OnlyFilename(filename)); - else - result = fileDlg.open(lastPath, filters, - OnlyFilename(filename)); - - if (result.second.empty()) - return result.second; - - lastPath = OnlyPath(result.second); - - if (result.second.find_first_of("#~$% ") == string::npos) - break; - - Alert::error(_("Invalid filename"), - _("Filename can't contain any " - "of these characters:\n" - "space, '#', '~', '$' or '%'.")); - } + if (save) + result = fileDlg.save(lastPath, filters, + OnlyFilename(filename)); + else + result = fileDlg.open(lastPath, filters, + OnlyFilename(filename)); return result.second; } @@ -150,25 +135,8 @@ string const browseDir(string const & pathname, FileDialog fileDlg(title, LFUN_SELECT_FILE_SYNC, dir1, dir2); - FileDialog::Result result; - - while (true) { - result = fileDlg.opendir(lastPath, - OnlyFilename(pathname)); - - if (result.second.empty()) - return result.second; - - lastPath = OnlyPath(result.second); - - if (result.second.find_first_of("#~$% ") == string::npos) - break; - - Alert::error(_("Invalid filename"), - _("Filename can't contain any " - "of these characters:\n" - "space, '#', '~', '$' or '%'.")); - } + FileDialog::Result const result = + fileDlg.opendir(lastPath, OnlyFilename(pathname)); return result.second; } diff --git a/src/frontends/qt2/ChangeLog b/src/frontends/qt2/ChangeLog index 58398bbb5d..80124a9915 100644 --- a/src/frontends/qt2/ChangeLog +++ b/src/frontends/qt2/ChangeLog @@ -1,3 +1,22 @@ +2005-05-13 Angus Leeming + + * QBibtex.C (build_dialog): + * QBibtexDialog.C (c-tor, bibEDChanged, addPressed): add a + PathValidator of the add_->BibED widget and use it to control + the activation state of the "Add" button. + + * QExternal.C (build_dialog, update_contents): + * QExternalDialog.C (c-tor): add a PathValidator of the fileED + widget. + + * QGraphics.C (build_dialog, update_contents): + * QGraphicsDialog.C (c-tor): add a PathValidator of the filename + widget. + + * QInclude.C (build_dialog, update_contents): + * QIncludeDialog.C (c-tor): add a PathValidator of the filenameED + widget. + 2005-05-09 Michael Schmitt * *.C: strip "LyX: " prefix from dialog titles; harmonize diff --git a/src/frontends/qt2/QBibtex.C b/src/frontends/qt2/QBibtex.C index 482fb3a7da..feb7bbc9ad 100644 --- a/src/frontends/qt2/QBibtex.C +++ b/src/frontends/qt2/QBibtex.C @@ -17,6 +17,9 @@ #include "ui/QBibtexAddDialogBase.h" #include "Qt2BC.h" #include "qt_helpers.h" +#include "validators.h" + +#include "lyxrc.h" #include "controllers/ControlBibtex.h" @@ -66,6 +69,11 @@ void QBibtex::build_dialog() void QBibtex::update_contents() { + PathValidator * path_validator = + getPathValidator(dialog_->add_->bibED); + if (path_validator) + path_validator->setChecker(kernel().docType(), lyxrc); + bool bibtopic = controller().usingBibtopic(); dialog_->databaseLB->clear(); diff --git a/src/frontends/qt2/QBibtexDialog.C b/src/frontends/qt2/QBibtexDialog.C index 5b4ef22ac3..4f93cf7685 100644 --- a/src/frontends/qt2/QBibtexDialog.C +++ b/src/frontends/qt2/QBibtexDialog.C @@ -13,10 +13,17 @@ #include "QBibtexDialog.h" #include "ui/QBibtexAddDialogBase.h" #include "QBibtex.h" + +#include "checkedwidgets.h" +#include "Qt2BC.h" #include "qt_helpers.h" +#include "validators.h" #include "controllers/ControlBibtex.h" +#include "controllers/ButtonPolicies.h" + #include "support/filetools.h" +#include "support/lstrings.h" #include #include @@ -24,6 +31,7 @@ #include using lyx::support::ChangeExtension; +using lyx::support::trim; using std::string; @@ -40,12 +48,41 @@ QBibtexDialog::QBibtexDialog(QBibtex * form) form, SLOT(slotClose())); add_ = new QBibtexAddDialogBase(this, "", true); - connect(add_->addPB, SIGNAL(clicked()), this, SLOT(addDatabase())); - connect(add_->addPB, SIGNAL(clicked()), this, SLOT(addDatabase())); - connect(add_->bibLB, SIGNAL(selected(QListBoxItem *)), this, SLOT(addDatabase())); - connect(add_->bibLB, SIGNAL(selected(QListBoxItem *)), add_, SLOT(accept())); - connect(add_->bibLB, SIGNAL(currentChanged(QListBoxItem *)), this, SLOT(availableChanged())); - connect(add_->browsePB, SIGNAL(clicked()), this, SLOT(browseBibPressed())); + Qt2BC * bcview = new Qt2BC(add_bc_); + add_bc_.view(bcview); + add_bc_.bp(new OkCancelPolicy); + + bcview->setOK(add_->addPB); + bcview->setCancel(add_->closePB); + + add_->bibED->setValidator(new PathValidator(false, add_->bibED)); + addCheckedLineEdit(add_bc_.view(), add_->bibED, 0); + + connect(add_->bibED, SIGNAL(textChanged(const QString&)), + this, SLOT(bibEDChanged())); + connect(add_->addPB, SIGNAL(clicked()), + this, SLOT(addDatabase())); + connect(add_->bibLB, SIGNAL(selected(QListBoxItem *)), + this, SLOT(addDatabase())); + connect(add_->bibLB, SIGNAL(selected(QListBoxItem *)), + add_, SLOT(accept())); + connect(add_->bibLB, SIGNAL(currentChanged(QListBoxItem *)), + this, SLOT(availableChanged())); + connect(add_->browsePB, SIGNAL(clicked()), + this, SLOT(browseBibPressed())); +} + + +QBibtexDialog::~QBibtexDialog() +{} + + +void QBibtexDialog::bibEDChanged() +{ + // Indicate to the button controller that the contents have + // changed. The actual test of validity is carried out by + // the checkedLineEdit. + add_bc_.valid(true); } @@ -82,7 +119,7 @@ void QBibtexDialog::browsePressed() void QBibtexDialog::browseBibPressed() { - string const file = form_->controller().browseBib(""); + string const file = trim(form_->controller().browseBib("")); if (!file.empty()) { string const f = ChangeExtension(file, ""); @@ -102,16 +139,18 @@ void QBibtexDialog::browseBibPressed() } } + void QBibtexDialog::addPressed() { add_->exec(); + add_bc_.valid(false); } void QBibtexDialog::addDatabase() { int const sel = add_->bibLB->currentItem(); - QString const file = add_->bibED->text(); + QString const file = trim(add_->bibED->text()); if (sel < 0 && file.isNull()) return; diff --git a/src/frontends/qt2/QBibtexDialog.h b/src/frontends/qt2/QBibtexDialog.h index fa6adc7f1d..f1ed4e563a 100644 --- a/src/frontends/qt2/QBibtexDialog.h +++ b/src/frontends/qt2/QBibtexDialog.h @@ -13,6 +13,7 @@ #define QBIBTEXDIALOG_H #include "ui/QBibtexDialogBase.h" +#include "ButtonController.h" class QBibtexAddDialogBase; @@ -26,6 +27,7 @@ class QBibtexDialog : public QBibtexDialogBase { public: QBibtexDialog(QBibtex * form); + ~QBibtexDialog(); QBibtexAddDialogBase * add_; @@ -38,12 +40,14 @@ protected slots: virtual void deletePressed(); virtual void databaseChanged(); virtual void availableChanged(); + void bibEDChanged(); protected: virtual void closeEvent(QCloseEvent * e); private: QBibtex * form_; + ButtonController add_bc_; }; } // namespace frontend diff --git a/src/frontends/qt2/QExternal.C b/src/frontends/qt2/QExternal.C index 47f232b467..829d76612f 100644 --- a/src/frontends/qt2/QExternal.C +++ b/src/frontends/qt2/QExternal.C @@ -31,6 +31,7 @@ #include "checkedwidgets.h" #include "lengthcombo.h" #include "qt_helpers.h" +#include "validators.h" #include #include @@ -320,6 +321,7 @@ void QExternal::build_dialog() addCheckedLineEdit(bcview(), dialog_->ybED, dialog_->lbLA); addCheckedLineEdit(bcview(), dialog_->xrED, dialog_->rtLA); addCheckedLineEdit(bcview(), dialog_->ytED, dialog_->rtLA); + addCheckedLineEdit(bcview(), dialog_->fileED, dialog_->fileLA); std::vector templates(controller().getTemplates()); @@ -343,6 +345,10 @@ void QExternal::build_dialog() void QExternal::update_contents() { + PathValidator * path_validator = getPathValidator(dialog_->fileED); + if (path_validator) + path_validator->setChecker(kernel().docType(), lyxrc); + dialog_->tab->setCurrentPage(0); InsetExternalParams const & params = controller().params(); diff --git a/src/frontends/qt2/QExternalDialog.C b/src/frontends/qt2/QExternalDialog.C index c951728856..c5045f684b 100644 --- a/src/frontends/qt2/QExternalDialog.C +++ b/src/frontends/qt2/QExternalDialog.C @@ -68,6 +68,8 @@ QExternalDialog::QExternalDialog(QExternal * form) widthED->setValidator(unsignedLengthValidator(widthED)); heightED->setValidator(unsignedLengthValidator(heightED)); + + fileED->setValidator(new PathValidator(true, fileED)); } diff --git a/src/frontends/qt2/QGraphics.C b/src/frontends/qt2/QGraphics.C index dc7a68ea8b..10c182fcaf 100644 --- a/src/frontends/qt2/QGraphics.C +++ b/src/frontends/qt2/QGraphics.C @@ -19,6 +19,7 @@ #include "QGraphicsDialog.h" #include "Qt2BC.h" #include "qt_helpers.h" +#include "validators.h" #include "lengthcommon.h" #include "lyxrc.h" @@ -114,6 +115,7 @@ void QGraphics::build_dialog() addCheckedLineEdit(bcview(), dialog_->lbY, dialog_->yL); addCheckedLineEdit(bcview(), dialog_->rtX, dialog_->xL_2); addCheckedLineEdit(bcview(), dialog_->rtY, dialog_->yL_2); + addCheckedLineEdit(bcview(), dialog_->filename, dialog_->filenameL); } @@ -131,6 +133,10 @@ int getItemNo(vector v, string const & s) { void QGraphics::update_contents() { + PathValidator * path_validator = getPathValidator(dialog_->filename); + if (path_validator) + path_validator->setChecker(kernel().docType(), lyxrc); + // clear and fill in the comboboxes vector const bb_units = lyx::frontend::getBBUnits(); dialog_->lbXunit->clear(); diff --git a/src/frontends/qt2/QGraphicsDialog.C b/src/frontends/qt2/QGraphicsDialog.C index efc2c99d33..e4361c10cf 100644 --- a/src/frontends/qt2/QGraphicsDialog.C +++ b/src/frontends/qt2/QGraphicsDialog.C @@ -58,6 +58,8 @@ QGraphicsDialog::QGraphicsDialog(QGraphics * form) displayscale->setValidator(new QIntValidator(displayscale)); height->setValidator(unsignedLengthValidator(height)); width->setValidator(unsignedLengthValidator(width)); + + filename->setValidator(new PathValidator(true, filename)); } diff --git a/src/frontends/qt2/QInclude.C b/src/frontends/qt2/QInclude.C index da4b2f03d5..df6ac70f87 100644 --- a/src/frontends/qt2/QInclude.C +++ b/src/frontends/qt2/QInclude.C @@ -12,8 +12,13 @@ #include "QIncludeDialog.h" #include "QInclude.h" + +#include "checkedwidgets.h" #include "Qt2BC.h" #include "qt_helpers.h" +#include "validators.h" + +#include "lyxrc.h" #include "controllers/ControlInclude.h" @@ -45,11 +50,17 @@ void QInclude::build_dialog() bcview().addReadOnly(dialog_->browsePB); bcview().addReadOnly(dialog_->visiblespaceCB); bcview().addReadOnly(dialog_->typeCO); + + addCheckedLineEdit(bcview(), dialog_->filenameED, dialog_->filenameLA); } void QInclude::update_contents() { + PathValidator * path_validator = getPathValidator(dialog_->filenameED); + if (path_validator) + path_validator->setChecker(kernel().docType(), lyxrc); + InsetCommandParams const & params = controller().params(); dialog_->filenameED->setText(toqstr(params.getContents())); diff --git a/src/frontends/qt2/QIncludeDialog.C b/src/frontends/qt2/QIncludeDialog.C index 5e998a76b3..15f207f5fe 100644 --- a/src/frontends/qt2/QIncludeDialog.C +++ b/src/frontends/qt2/QIncludeDialog.C @@ -12,6 +12,7 @@ #include "QIncludeDialog.h" #include "QInclude.h" +#include "validators.h" #include #include @@ -29,6 +30,8 @@ QIncludeDialog::QIncludeDialog(QInclude * form) form, SLOT(slotOK())); connect(closePB, SIGNAL(clicked()), form, SLOT(slotClose())); + + filenameED->setValidator(new PathValidator(true, filenameED)); } diff --git a/src/frontends/xforms/ChangeLog b/src/frontends/xforms/ChangeLog index d7e30d1ac9..ffaa2a1894 100644 --- a/src/frontends/xforms/ChangeLog +++ b/src/frontends/xforms/ChangeLog @@ -1,3 +1,13 @@ +2005-05-13 Angus Leeming + + * checkedwidgets.[Ch] (CheckedPath): new class that determines + whether the input file name is valid or not. + + * FormExternal.[Ch]: + * FormGraphics.[Ch]: + * FormInclude.[Ch]: use the new CheckedPath to control the + activation state of the "OK", "Apply" buttons. + 2005-05-09 Lars Gullik Bjønnes * forms/Makefile.am: add a distclean-local target to remove @@ -12,8 +22,8 @@ 2005-05-04 Michael Schmitt * forms/form_preferences.fd: fix capitalization. - * Form*.C: Change dialog titles - harmonize with Qt frontend and - menu entries; fix capitalization; change "citation reference" + * Form*.C: Change dialog titles - harmonize with Qt frontend and + menu entries; fix capitalization; change "citation reference" to "citation". * FormTexinfo.C: correct tooltip. diff --git a/src/frontends/xforms/FormExternal.C b/src/frontends/xforms/FormExternal.C index 7bffb9c475..5d15458775 100644 --- a/src/frontends/xforms/FormExternal.C +++ b/src/frontends/xforms/FormExternal.C @@ -319,7 +319,8 @@ void getExtra(external::ExtraData & data, typedef FormController > base_class; FormExternal::FormExternal(Dialog & parent) - : base_class(parent, _("External Material")) + : base_class(parent, _("External Material")), + file_checker_(0) {} @@ -366,6 +367,8 @@ void FormExternal::build() bcview().addReadOnly(options_->choice_option); bcview().addReadOnly(options_->input_option); + file_checker_ = &addCheckedPath(bcview(), true, file_->input_file); + // initial setting // addCheckedPositiveFloat(bcview(), scale_->input_width); // As I haven't written addCheckedPositiveFloat, we default to @@ -464,6 +467,8 @@ void FormExternal::build() void FormExternal::update() { + file_checker_->setChecker(kernel().docType(), lyxrc); + fl_set_folder_bynumber(dialog_->tabfolder, 1); InsetExternalParams const & params = controller().params(); diff --git a/src/frontends/xforms/FormExternal.h b/src/frontends/xforms/FormExternal.h index f48c160be8..6eb63e400d 100644 --- a/src/frontends/xforms/FormExternal.h +++ b/src/frontends/xforms/FormExternal.h @@ -20,6 +20,7 @@ namespace lyx { namespace frontend { +class CheckedPath; class ControlExternal; struct FD_external; struct FD_external_file; @@ -67,6 +68,9 @@ private: void updateComboChange(); void widthUnitChanged(); + // Accessor to checker owned by the button controller. + CheckedPath * file_checker_; + MapType extra_; TabMap tabmap_; diff --git a/src/frontends/xforms/FormGraphics.C b/src/frontends/xforms/FormGraphics.C index d794ac0f42..a72e52d05c 100644 --- a/src/frontends/xforms/FormGraphics.C +++ b/src/frontends/xforms/FormGraphics.C @@ -75,7 +75,8 @@ bool const scalableTabfolders = true; typedef FormController > base_class; FormGraphics::FormGraphics(Dialog & parent) - : base_class(parent, _("Graphics"), scalableTabfolders) + : base_class(parent, _("Graphics"), scalableTabfolders), + file_checker_(0) {} @@ -110,6 +111,8 @@ void FormGraphics::build() bcview().addReadOnly(file_->check_draft); bcview().addReadOnly(file_->check_nounzip); + file_checker_ = &addCheckedPath(bcview(), true, file_->input_filename); + // Check validity of "length + unit" input. addCheckedGlueLength(bcview(), file_->input_width); addCheckedGlueLength(bcview(), file_->input_height); @@ -431,7 +434,10 @@ void FormGraphics::apply() } -void FormGraphics::update() { +void FormGraphics::update() +{ + file_checker_->setChecker(kernel().docType(), lyxrc); + // Update dialog with details from inset InsetGraphicsParams & igp = controller().params(); diff --git a/src/frontends/xforms/FormGraphics.h b/src/frontends/xforms/FormGraphics.h index 85ee23a743..97364f3472 100644 --- a/src/frontends/xforms/FormGraphics.h +++ b/src/frontends/xforms/FormGraphics.h @@ -20,6 +20,7 @@ namespace lyx { namespace frontend { +class CheckedPath; class ControlGraphics; struct FD_graphics; struct FD_graphics_file; @@ -49,6 +50,9 @@ private: /// Filter the inputs on callback from xforms virtual ButtonPolicy::SMInput input(FL_OBJECT *, long); + // Accessor to checker owned by the button controller. + CheckedPath * file_checker_; + /// Real GUI implementation. boost::scoped_ptr file_; /// diff --git a/src/frontends/xforms/FormInclude.C b/src/frontends/xforms/FormInclude.C index 57bbb468e5..632af3beb8 100644 --- a/src/frontends/xforms/FormInclude.C +++ b/src/frontends/xforms/FormInclude.C @@ -16,10 +16,13 @@ #include "ControlInclude.h" #include "forms/form_include.h" +#include "checkedwidgets.h" #include "Tooltips.h" #include "xforms_helpers.h" // setEnabled #include "xformsBC.h" +#include "lyxrc.h" + #include "support/lstrings.h" // strip #include "lyx_forms.h" @@ -35,7 +38,8 @@ namespace frontend { typedef FormController > base_class; FormInclude::FormInclude(Dialog & parent) - : base_class(parent, _("Child Document")) + : base_class(parent, _("Child Document")), + file_checker_(0) {} @@ -58,6 +62,8 @@ void FormInclude::build() bcview().addReadOnly(dialog_->radio_useinclude); bcview().addReadOnly(dialog_->radio_verbatim); + file_checker_ = &addCheckedPath(bcview(), true, dialog_->input_filename); + type_.init(dialog_->radio_useinput, ControlInclude::INPUT); type_.init(dialog_->radio_useinclude, ControlInclude::INCLUDE); type_.init(dialog_->radio_verbatim, ControlInclude::VERBATIM); @@ -84,6 +90,8 @@ void FormInclude::build() void FormInclude::update() { + file_checker_->setChecker(kernel().docType(), lyxrc); + string const filename = controller().params().getContents(); string const cmdname = controller().params().getCmdName(); bool const preview = static_cast((controller().params().preview())); diff --git a/src/frontends/xforms/FormInclude.h b/src/frontends/xforms/FormInclude.h index 5bd8464335..2846e3dd90 100644 --- a/src/frontends/xforms/FormInclude.h +++ b/src/frontends/xforms/FormInclude.h @@ -19,6 +19,7 @@ namespace lyx { namespace frontend { +class CheckedPath; class ControlInclude; struct FD_include; @@ -39,6 +40,9 @@ private: /// Filter the inputs on callback from xforms virtual ButtonPolicy::SMInput input(FL_OBJECT *, long); + // Accessor to checker owned by the button controller. + CheckedPath * file_checker_; + /// include type RadioButtonGroup type_; }; diff --git a/src/frontends/xforms/checkedwidgets.C b/src/frontends/xforms/checkedwidgets.C index 532823e34f..9ea5dbf0e1 100644 --- a/src/frontends/xforms/checkedwidgets.C +++ b/src/frontends/xforms/checkedwidgets.C @@ -13,32 +13,53 @@ #include "checkedwidgets.h" #include "xforms_helpers.h" + +#include "gettext.h" #include "lyxgluelength.h" +#include "lyxrc.h" + +#include "frontends/Alert.h" +#include "frontends/controllers/Kernel.h" #include "support/lstrings.h" #include "lyx_forms.h" +#include + + +using lyx::support::isStrDbl; using std::string; namespace lyx { - -using support::isStrDbl; - namespace frontend { -void addCheckedLyXLength(BCView & bcview, - FL_OBJECT * input, FL_OBJECT * label) +CheckedLyXLength & +addCheckedLyXLength(BCView & bcview, FL_OBJECT * input, FL_OBJECT * label) { - bcview.addCheckedWidget(new CheckedLyXLength(input, label)); + CheckedLyXLength * cw(new CheckedLyXLength(input, label)); + bcview.addCheckedWidget(cw); + return *cw; } -void addCheckedGlueLength(BCView & bcview, - FL_OBJECT * input, FL_OBJECT * label) +CheckedGlueLength & +addCheckedGlueLength(BCView & bcview, FL_OBJECT * input, FL_OBJECT * label) { - bcview.addCheckedWidget(new CheckedGlueLength(input, label)); + CheckedGlueLength * cw(new CheckedGlueLength(input, label)); + bcview.addCheckedWidget(cw); + return *cw; +} + + +CheckedPath & +addCheckedPath(BCView & bcview, bool acceptable_if_empty, + FL_OBJECT * input, FL_OBJECT * label) +{ + CheckedPath * cw(new CheckedPath(acceptable_if_empty, input, label)); + bcview.addCheckedWidget(cw); + return *cw; } @@ -107,5 +128,87 @@ bool CheckedGlueLength::check() const return valid; } + +CheckedPath::CheckedPath(bool acceptable_if_empty, + FL_OBJECT * input, FL_OBJECT * label) + : input_(input), label_(label ? label : input), + acceptable_if_empty_(acceptable_if_empty), + latex_doc_(false), + tex_allows_spaces_(false) +{} + + +void CheckedPath::setChecker(lyx::frontend::KernelDocType const & type, + LyXRC const & lyxrc) +{ + latex_doc_ = type == lyx::frontend::Kernel::LATEX; + tex_allows_spaces_ = lyxrc.tex_allows_spaces; +} + + +namespace { + +string const printable_list(string const & invalid_chars) +{ + std::ostringstream ss; + string::const_iterator const begin = invalid_chars.begin(); + string::const_iterator const end = invalid_chars.end(); + string::const_iterator it = begin; + + for (; it != end; ++it) { + if (it != begin) + ss << ", "; + if (*it == ' ') + ss << _("space"); + else + ss << *it; + } + + return ss.str(); +} + +} // namespace anon + + +bool CheckedPath::check() const +{ + if (!latex_doc_) { + setWidget(true, input_, label_); + return true; + } + + if (!isActive(input_)) { + setWidget(true, input_, label_); + return true; + } + + string const text = getString(input_); + if (text.empty()) { + setWidget(acceptable_if_empty_, input_, label_); + return acceptable_if_empty_; + } + + string invalid_chars("#$%{}()[]:\"^"); + if (!tex_allows_spaces_) + invalid_chars += ' '; + + bool valid = true; + if (text.find_first_of(invalid_chars) != string::npos) { + + static int counter = 0; + if (counter == 0) { + Alert::error(_("Invalid filename"), + _("LyX does not provide LateX support for file names containing any of these characters:\n") + + printable_list(invalid_chars)); + } + ++counter; + valid = false; + } + + // set the color of label and input widget + setWidget(valid, input_, label_); + return valid; +} + } // namespace frontend } // namespace lyx diff --git a/src/frontends/xforms/checkedwidgets.h b/src/frontends/xforms/checkedwidgets.h index 1088bbcaa9..27885a1b01 100644 --- a/src/frontends/xforms/checkedwidgets.h +++ b/src/frontends/xforms/checkedwidgets.h @@ -18,11 +18,22 @@ namespace lyx { namespace frontend { -void addCheckedLyXLength(BCView & bcview, - FL_OBJECT * input, FL_OBJECT * label = 0); +class CheckedLyXLength; +class CheckedGlueLength; +class CheckedPath; + + +// +CheckedLyXLength & +addCheckedLyXLength(BCView & bcview, FL_OBJECT * input, FL_OBJECT * label = 0); + +CheckedGlueLength & +addCheckedGlueLength(BCView & bcview, FL_OBJECT * input, FL_OBJECT * label = 0); + +CheckedPath & +addCheckedPath(BCView & bcview, bool acceptable_if_empty, + FL_OBJECT * input, FL_OBJECT * label = 0); -void addCheckedGlueLength(BCView & bcview, - FL_OBJECT * input, FL_OBJECT * label = 0); class CheckedLyXLength : public CheckedWidget { public: @@ -62,4 +73,49 @@ private: } // namespace frontend } // namespace lyx + +// Forward declarations +class LyXRC; + +namespace lyx { +namespace frontend { + +class KernelDocType; + + +class CheckedPath : public CheckedWidget { +public: + /** The label widget's label will be turned red if input + * does not make a valid file path. + * If label == 0, then the label of input will be used. + * If @c acceptable_if_empty is @c true then an empty path + * is regarded as acceptable. + */ + CheckedPath(bool acceptable_if_empty, + FL_OBJECT * input, FL_OBJECT * label = 0); + + /** Define now to perform the check. + * @param doc_type checks are activated only for @c LATEX docs. + * @param lyxrc contains a @c tex_allows_spaces member that + * is used to define what is legal. + */ + void setChecker(lyx::frontend::KernelDocType const & doc_type, + LyXRC const & lyxrc); + +private: + /// + virtual bool check() const; + + /// + FL_OBJECT * input_; + FL_OBJECT * label_; + + bool acceptable_if_empty_; + bool latex_doc_; + bool tex_allows_spaces_; +}; + +} // namespace frontend +} // namespace lyx + #endif // CHECKEDWIDGETS_H