]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/qt_helpers.cpp
do what the FIXME suggested
[lyx.git] / src / frontends / qt4 / qt_helpers.cpp
index d89f1b2bf7f7cf6e97d2cdba0b0bf77367dd12c4..02f34068d7b1c3c6031f4a544abb7a1f0548f004 100644 (file)
 
 #include <config.h>
 
-#include "LengthCombo.h"
 #include "qt_helpers.h"
 
-#include "lengthcommon.h"
-#include "gettext.h"
+#include "FileDialog.h"
+#include "LengthCombo.h"
 
-#include "support/os.h"
-#include "support/lstrings.h"
-#include "support/convert.h"
+#include "frontends/alert.h"
 
-#include "debug.h"
+#include "Language.h"
+#include "Length.h"
+
+#include "support/debug.h"
+#include "support/filetools.h"
+#include "support/gettext.h"
+#include "support/lstrings.h"
+#include "support/lyxalgo.h"
+#include "support/os.h"
+#include "support/Package.h"
+#include "support/Path.h"
+#include "support/Systemcall.h"
 
 #include <QComboBox>
 #include <QCheckBox>
-#include <qlineedit.h>
-#include <qtextcodec.h>
+#include <QPalette>
+#include <QLineEdit>
+
+#include <boost/cregex.hpp>
 
 #include <algorithm>
+#include <fstream>
+#include <locale>
 
+using namespace std;
+using namespace lyx::support;
 
 namespace lyx {
-
-using support::isStrDbl;
-
-using std::vector;
-using std::make_pair;
-using std::string;
-using std::pair;
-using std::endl;
-
-
-string makeFontName(string const & family, string const & foundry)
-{
-       if (foundry.empty())
-               return family;
-       return family + " [" + foundry + ']';
-}
-
-
-pair<string, string> parseFontName(string const & name)
-{
-       string::size_type const idx = name.find('[');
-       if (idx == string::npos || idx == 0)
-               return make_pair(name, string());
-       return make_pair(name.substr(0, idx - 1),
-                        name.substr(idx + 1, name.size() - idx - 2));
-}
-
+namespace frontend {
 
 string widgetsToLength(QLineEdit const * input, LengthCombo const * combo)
 {
@@ -96,8 +84,8 @@ Length widgetsToLength(QLineEdit const * input, QComboBox const * combo)
 void lengthToWidgets(QLineEdit * input, LengthCombo * combo,
                      Length const & len, Length::UNIT /*defaultUnit*/)
 {
-       combo->setCurrentItem(Length(len).unit());
-       input->setText(toqstr(convert<string>(Length(len).value())));
+       combo->setCurrentItem(len.unit());
+       input->setText(QString::number(Length(len).value()));
 }
 
 
@@ -128,19 +116,18 @@ void lengthAutoToWidgets(QLineEdit * input, LengthCombo * combo,
 }
 
 
-//NOTE "CB" here because we probably will want one of these
-//for labeled sets, as well.
-void setAutoTextCB(QCheckBox * checkBox, QLineEdit * lineEdit,
-       LengthCombo * lengthCombo)
+void setValid(QWidget * widget, bool valid)
 {
-       if (!checkBox->isChecked())
-               lengthToWidgets(lineEdit, lengthCombo,
-                               "auto", lengthCombo->currentLengthItem());
-       else if (lineEdit->text() == "auto")
-               lengthToWidgets(lineEdit, lengthCombo, string(),
-                               lengthCombo->currentLengthItem());
+       if (valid) {
+               widget->setPalette(QPalette());
+       } else {
+               QPalette pal = widget->palette();
+               pal.setColor(QPalette::Active, QPalette::Foreground, QColor(255, 0, 0));
+               widget->setPalette(pal);
+       }
 }
 
+} // namespace frontend
 
 QString const qt_(char const * str, const char *)
 {
@@ -153,63 +140,207 @@ QString const qt_(string const & str)
        return toqstr(_(str));
 }
 
+namespace {
 
-docstring const formatted(docstring const & text, int w)
+class Sorter
 {
-       docstring sout;
+public:
+#if !defined(USE_WCHAR_T) && defined(__GNUC__)
+       bool operator()(LanguagePair const & lhs, LanguagePair const & rhs) const {
+               return lhs.first < rhs.first;
+       }
+#else
+       Sorter() : loc_ok(true)
+       {
+               try {
+                       loc_ = locale("");
+               } catch (...) {
+                       loc_ok = false;
+               }
+       };
+
+       bool operator()(LanguagePair const & lhs,
+                       LanguagePair const & rhs) const {
+               if (loc_ok)
+                       return loc_(lhs.first, rhs.first);
+               else
+                       return lhs.first < rhs.first;
+       }
+private:
+       locale loc_;
+       bool loc_ok;
+#endif
+};
 
-       if (text.empty())
-               return sout;
 
-       docstring::size_type curpos = 0;
-       docstring line;
+} // namespace anon
 
-       for (;;) {
-               docstring::size_type const nxtpos1 = text.find(' ',  curpos);
-               docstring::size_type const nxtpos2 = text.find('\n', curpos);
-               docstring::size_type const nxtpos = std::min(nxtpos1, nxtpos2);
 
-               docstring const word =
-                       nxtpos == docstring::npos ?
-                       text.substr(curpos) :
-                       text.substr(curpos, nxtpos - curpos);
+vector<LanguagePair> const getLanguageData(bool character_dlg)
+{
+       size_t const size = languages.size() + (character_dlg ? 2 : 0);
 
-               bool const newline = (nxtpos2 != docstring::npos &&
-                                     nxtpos2 < nxtpos1);
+       vector<LanguagePair> langs(size);
 
-               docstring const line_plus_word =
-                       line.empty() ? word : line + char_type(' ') + word;
+       if (character_dlg) {
+               langs[0].first = _("No change");
+               langs[0].second = "ignore";
+               langs[1].first = _("Reset");
+               langs[1].second = "reset";
+       }
 
-               // FIXME: make w be size_t
-               if (int(line_plus_word.length()) >= w) {
-                       sout += line + char_type('\n');
-                       if (newline) {
-                               sout += word + char_type('\n');
-                               line.erase();
-                       } else {
-                               line = word;
-                       }
+       size_t i = character_dlg ? 2 : 0;
+       for (Languages::const_iterator cit = languages.begin();
+            cit != languages.end(); ++cit) {
+               langs[i].first  = _(cit->second.display());
+               langs[i].second = cit->second.lang();
+               ++i;
+       }
 
-               } else if (newline) {
-                       sout += line_plus_word + char_type('\n');
-                       line.erase();
+       // Don't sort "ignore" and "reset"
+       vector<LanguagePair>::iterator begin = character_dlg ?
+               langs.begin() + 2 : langs.begin();
 
-               } else {
-                       if (!line.empty())
-                               line += char_type(' ');
-                       line += word;
-               }
+       sort(begin, langs.end(), Sorter());
 
-               if (nxtpos == docstring::npos) {
-                       if (!line.empty())
-                               sout += line;
-                       break;
-               }
+       return langs;
+}
 
-               curpos = nxtpos + 1;
-       }
 
-       return sout;
+docstring browseFile(docstring const & filename, docstring const & title,
+       FileFilterList const & filters, bool save,
+       docstring const & label1, docstring const & dir1,
+       docstring const & label2, docstring const & dir2)
+{
+       docstring lastPath = from_ascii(".");
+       if (!filename.empty())
+               lastPath = from_utf8(onlyPath(to_utf8(filename)));
+
+       FileDialog dlg(title, LFUN_SELECT_FILE_SYNC);
+       dlg.setButton1(label1, dir1);
+       dlg.setButton2(label2, dir2);
+
+       FileDialog::Result result;
+
+       if (save)
+               result = dlg.save(lastPath, filters,
+                                     from_utf8(onlyFilename(to_utf8(filename))));
+       else
+               result = dlg.open(lastPath, filters,
+                                     from_utf8(onlyFilename(to_utf8(filename))));
+
+       return result.second;
+}
+
+
+docstring browseRelFile(docstring const & filename, docstring const & refpath,
+       docstring const & title, FileFilterList const & filters, bool save,
+       docstring const & label1, docstring const & dir1,
+       docstring const & label2, docstring const & dir2)
+{
+       docstring const fname = from_utf8(makeAbsPath(
+               to_utf8(filename), to_utf8(refpath)).absFilename());
+
+       docstring const outname = browseFile(fname, title, filters, save,
+                                         label1, dir1, label2, dir2);
+       docstring const reloutname = makeRelPath(outname, refpath);
+       if (prefixIs(reloutname, from_ascii("../")))
+               return outname;
+       else
+               return reloutname;
+}
+
+
+docstring browseLibFile(docstring const & dir, docstring const & name,
+       docstring const & ext, docstring const & title,
+       FileFilterList const & filters)
+{
+       // FIXME UNICODE
+       docstring const label1 = _("System files|#S#s");
+       docstring const dir1 =
+               from_utf8(addName(package().system_support().absFilename(), to_utf8(dir)));
+
+       docstring const label2 = _("User files|#U#u");
+       docstring const dir2 =
+               from_utf8(addName(package().user_support().absFilename(), to_utf8(dir)));
+
+       docstring const result = browseFile(from_utf8(
+               libFileSearch(to_utf8(dir), to_utf8(name), to_utf8(ext)).absFilename()),
+               title, filters, false, dir1, dir2);
+
+       // remove the extension if it is the default one
+       docstring noextresult;
+       if (from_utf8(getExtension(to_utf8(result))) == ext)
+               noextresult = from_utf8(removeExtension(to_utf8(result)));
+       else
+               noextresult = result;
+
+       // remove the directory, if it is the default one
+       docstring const file = from_utf8(onlyFilename(to_utf8(noextresult)));
+       if (from_utf8(libFileSearch(to_utf8(dir), to_utf8(file), to_utf8(ext)).absFilename()) == result)
+               return file;
+       else
+               return noextresult;
+}
+
+
+docstring browseDir(docstring const & pathname, docstring const & title,
+       docstring const & label1, docstring const & dir1,
+       docstring const & label2, docstring const & dir2)
+{
+       docstring lastPath = from_ascii(".");
+       if (!pathname.empty())
+               lastPath = from_utf8(onlyPath(to_utf8(pathname)));
+
+       FileDialog dlg(title, LFUN_SELECT_FILE_SYNC);
+       dlg.setButton1(label1, dir1);
+       dlg.setButton2(label2, dir2);
+
+       FileDialog::Result const result =
+               dlg.opendir(lastPath, from_utf8(onlyFilename(to_utf8(pathname))));
+
+       return result.second;
+}
+
+
+void rescanTexStyles()
+{
+       // Run rescan in user lyx directory
+       PathChanger p(package().user_support());
+       FileName const command = libFileSearch("scripts", "TeXFiles.py");
+       Systemcall one;
+       int const status = one.startscript(Systemcall::Wait,
+                       os::python() + ' ' +
+                       quoteName(command.toFilesystemEncoding()));
+       if (status == 0)
+               return;
+       // FIXME UNICODE
+       frontend::Alert::error(_("Could not update TeX information"),
+               bformat(_("The script `%s' failed."), from_utf8(command.absFilename())));
+}
+
+
+void getTexFileList(string const & filename, vector<string> & list)
+{
+       list.clear();
+       FileName const file = libFileSearch("", filename);
+       if (file.empty())
+               return;
+
+       // FIXME Unicode.
+       vector<docstring> doclist = 
+               getVectorFromString(file.fileContents("UTF-8"), from_ascii("\n"));
+
+       // Normalise paths like /foo//bar ==> /foo/bar
+       boost::RegEx regex("/{2,}");
+       vector<docstring>::iterator it  = doclist.begin();
+       vector<docstring>::iterator end = doclist.end();
+       for (; it != end; ++it)
+               list.push_back(regex.Merge(to_utf8(*it), "/"));
+
+       // remove empty items and duplicates
+       list.erase(remove(list.begin(), list.end(), ""), list.end());
+       eliminate_duplicates(list);
 }
 
 } // namespace lyx