]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/GuiLyXFiles.cpp
Use <cstdint> instead of <boost/cstdint.hpp>
[lyx.git] / src / frontends / qt4 / GuiLyXFiles.cpp
index 2e91f320a484e94098129153d503fba1e2097a5f..98c43419fdc29c3e4cfcb5e2e4bbcb4aceb6d907 100644 (file)
@@ -38,9 +38,20 @@ using namespace lyx::support;
 namespace lyx {
 namespace frontend {
 
+namespace {
 
-void GuiLyXFiles::getFiles(QMap<QString, QString> & in, QString const type)
+QString const guiString(QString in)
 {
+       // recode specially encoded chars in file names (URL encoding and underbar)
+       return QString(QByteArray::fromPercentEncoding(in.toUtf8())).replace('_', ' ');
+}
+
+} // namespace anon
+
+
+QMap<QString, QString> GuiLyXFiles::getFiles()
+{
+       QMap<QString, QString> result;
        // We look for lyx files in the subdirectory dir of
        //   1) user_lyxdir
        //   2) build_lyxdir (if not empty)
@@ -52,16 +63,20 @@ void GuiLyXFiles::getFiles(QMap<QString, QString> & in, QString const type)
        QStringList relpaths;
 
        // The three locations to look at.
-       string const user = addPath(package().user_support().absFileName(), fromqstr(type));
-       string const build = addPath(package().build_support().absFileName(), fromqstr(type));
-       string const system = addPath(package().system_support().absFileName(), fromqstr(type));
+       string const user = addPath(package().user_support().absFileName(), fromqstr(type_));
+       string const build = addPath(package().build_support().absFileName(), fromqstr(type_));
+       string const system = addPath(package().system_support().absFileName(), fromqstr(type_));
 
        available_languages_.insert(toqstr("en"), qt_("English"));
 
-       // Search in the base path
-       dirs << toqstr(user)
-            << toqstr(build)
-            << toqstr(system);
+       QString const type = fileTypeCO->itemData(fileTypeCO->currentIndex()).toString();
+
+       // Search in the base paths
+       if (type == "all" || type == "user")
+               dirs << toqstr(user);
+       if (type == "all" || type == "system")
+               dirs << toqstr(build)
+                    << toqstr(system);
 
        for (int i = 0; i < dirs.size(); ++i) {
                QString const dir = dirs.at(i);
@@ -79,9 +94,6 @@ void GuiLyXFiles::getFiles(QMap<QString, QString> & in, QString const type)
                        if (s != -1) {
                                // <cat>/<subcat>/
                                cat = relpath.left(s);
-                               int sc = relpath.indexOf('/', s + 1);
-                               QString const subcat = (sc == -1) ?
-                                                       QString() : relpath.mid(s + 1, sc - s - 1);
                                if (all_languages_.contains(cat)
                                    && !all_languages_.contains(dir.right(dir.lastIndexOf('/')))) {
                                        QMap<QString, QString>::const_iterator li = all_languages_.find(cat);
@@ -89,17 +101,25 @@ void GuiLyXFiles::getFiles(QMap<QString, QString> & in, QString const type)
                                        if (!available_languages_.contains(li.key()))
                                                available_languages_.insert(li.key(), li.value());
                                        localization = cat;
+                                       int sc = relpath.indexOf('/', s + 1);
+                                       cat = (sc == -1) ? qt_("General") : relpath.mid(s + 1, sc - s - 1);
+                                       s = sc;
+                               }
+                               if (s != -1) {
+                                       int sc = relpath.indexOf('/', s + 1);
+                                       QString const subcat = (sc == -1) ?
+                                                               QString() : relpath.mid(s + 1, sc - s - 1);
+                                       if (!subcat.isEmpty())
+                                               cat += '/' + subcat;
                                }
-                               if (!subcat.isEmpty())
-                                       cat += '/' + subcat;
                        }
                        if (!relpaths.contains(relpath)) {
                                relpaths.append(relpath);
-                               if (localization == "en")
-                                       in.insert(relpath, cat);
-                               else
+                               if (localization != "en")
                                        // strip off lang/
                                        relpath = relpath.mid(relpath.indexOf('/') + 1);
+                               result.insert(relpath, cat);
+                                                                       
                                QMap<QString, QString> lm;
                                if (localizations_.contains(relpath))
                                        lm = localizations_.find(relpath).value();
@@ -126,13 +146,14 @@ void GuiLyXFiles::getFiles(QMap<QString, QString> & in, QString const type)
        // pre-fill the language combo (it will be updated once an item 
        // has been clicked)
        languageCO->clear();
-       languageCO->addItem(qt_("English"), toqstr("en"));
        QMap<QString, QString>::const_iterator i =available_languages_.constBegin();
        while (i != available_languages_.constEnd()) {
                languageCO->addItem(i.value(), i.key());
                ++i;
        }
        setLanguage();
+       languageLA->setText(qt_("Preferred &Language:"));
+       return result;
 }
 
 
@@ -204,6 +225,12 @@ GuiLyXFiles::GuiLyXFiles(GuiView & lv)
        //filesLW->setViewMode(QListView::ListMode);
        filesLW->setIconSize(QSize(22, 22));
 
+       QIcon user_icon(getPixmap("images/", "lyxfiles-user", "svgz,png"));
+       QIcon system_icon(getPixmap("images/", "lyxfiles-system", "svgz,png"));
+       fileTypeCO->addItem(qt_("User and System Files"), toqstr("all"));
+       fileTypeCO->addItem(user_icon, qt_("User Files Only"), toqstr("user"));
+       fileTypeCO->addItem(system_icon, qt_("System Files Only"), toqstr("system"));
+
        setFocusProxy(filter_);
 }
 
@@ -212,6 +239,8 @@ QString const GuiLyXFiles::getSuffix()
 {
        if (type_ == "bind" || type_ == "ui")
                return toqstr(".") + type_;
+       else if (type_ == "kbd")
+               return ".kmap";
        
        return ".lyx";
 }
@@ -238,6 +267,9 @@ void GuiLyXFiles::on_fileTypeCO_activated(int)
 void GuiLyXFiles::on_languageCO_activated(int i)
 {
        savelang_ = languageCO->itemData(i).toString();
+       if (!filesLW->currentItem())
+               return;
+
        filesLW->currentItem()->setData(0, Qt::ToolTipRole, getRealPath());
        changed();
 }
@@ -269,15 +301,25 @@ void GuiLyXFiles::on_filesLW_itemClicked(QTreeWidgetItem * item, int)
                        languageCO->addItem(i.value(), i.key());
                ++i;
        }
+       languageLA->setText(qt_("File &Language:"));
        languageCO->setToolTip(qt_("All available languages of the selected file are displayed here.\n"
                                   "The selected language version will be opened."));
        setLanguage();
-       filesLW->currentItem()->setData(0, Qt::ToolTipRole, getRealPath());
+       QString const realpath = getRealPath();
+       filesLW->currentItem()->setData(0, Qt::ToolTipRole, realpath);
+       QIcon user_icon(getPixmap("images/", "lyxfiles-user", "svgz,png"));
+       QIcon system_icon(getPixmap("images/", "lyxfiles-system", "svgz,png"));
+       QIcon file_icon = (realpath.startsWith(toqstr(package().user_support().absFileName()))) ?
+                       user_icon : system_icon;
+       item->setIcon(0, file_icon);
 }
 
 
 void GuiLyXFiles::setLanguage()
 {
+       // Enable language selection only if there is a selection.
+       languageCO->setEnabled(languageCO->count() > 1);
+       languageLA->setEnabled(languageCO->count() > 1);
        // first try last setting
        if (!savelang_.isEmpty()) {
                int index = languageCO->findData(savelang_);
@@ -304,17 +346,43 @@ void GuiLyXFiles::setLanguage()
 
 void GuiLyXFiles::on_browsePB_pressed()
 {
-       bool const examples = (type_ == "examples");
-       FileDialog dlg(qt_("Select template file"));
-       dlg.setButton1(qt_("D&ocuments"), toqstr(lyxrc.document_path));
-       if (examples)
-               dlg.setButton2(qt_("&Examples"), toqstr(lyxrc.example_path));
-       else
-               dlg.setButton2(qt_("&Templates"), toqstr(lyxrc.template_path));
+       QString path1 = toqstr(lyxrc.document_path);
+       QString path2 = toqstr(lyxrc.example_path);
+       QString title = qt_("Select example file");
+       QString filter = qt_("LyX Documents (*.lyx)");
+       QString b1 = qt_("D&ocuments");
+       QString b2 = qt_("&Examples");
+
+       if (type_ == "templates") {
+               path2 = toqstr(lyxrc.template_path);
+               title = qt_("Select template file");
+               b1 = qt_("D&ocuments");
+               b2 = qt_("&Templates");
+       }
+       else if (type_ != "examples") {
+               path1 = toqstr(addName(package().user_support().absFileName(), fromqstr(type_)));
+               path2 = toqstr(addName(package().system_support().absFileName(), fromqstr(type_)));
+               b1 = qt_("&User files");
+               b2 = qt_("&System files");
+       }
+       if (type_ == "ui") {
+               title = qt_("Chose UI file");
+               filter = qt_("LyX UI Files (*.ui)");
+       }
+       if (type_ == "bind") {
+               title = qt_("Chose bind file");
+               filter = qt_("LyX Bind Files (*.bind)");
+       }
+       if (type_ == "kbd") {
+               title = qt_("Chose keyboard map");
+               filter = qt_("LyX Keymap Files (*.kmap)");
+       }
+
+       FileDialog dlg(title);
+       dlg.setButton1(b1, path1);
+       dlg.setButton2(b2, path2);
 
-       FileDialog::Result result = dlg.open(examples ? toqstr(lyxrc.example_path)
-                                                     : toqstr(lyxrc.template_path),
-                                QStringList(qt_("LyX Documents (*.lyx)")));
+       FileDialog::Result result = dlg.open(path2, QStringList(filter));
 
        if (result.first != FileDialog::Later && !result.second.isEmpty()) {
                file_ = toqstr(FileName(fromqstr(result.second)).absFileName());
@@ -326,10 +394,8 @@ void GuiLyXFiles::on_browsePB_pressed()
 
 void GuiLyXFiles::updateContents()
 {
-       QString type = fileTypeCO->itemData(fileTypeCO->currentIndex()).toString();
-       QMap<QString, QString> files;
        languageCO->clear();
-       getFiles(files, type);
+       QMap<QString, QString> files = getFiles();
        languageCO->model()->sort(0);
 
        filesLW->clear();
@@ -341,6 +407,7 @@ void GuiLyXFiles::updateContents()
        capfont.setBold(true);
        while (it != files.constEnd()) {
                QFileInfo const info = QFileInfo(it.key());
+               QString const realpath = getRealPath(it.key());
                QString cat = it.value();
                QString subcat;
                QString catsave;
@@ -348,10 +415,9 @@ void GuiLyXFiles::updateContents()
                        catsave = cat;
                        cat = catsave.left(catsave.indexOf('/'));
                        subcat = toqstr(translateIfPossible(
-                                       qstring_to_ucs4(catsave.mid(
-                                               catsave.indexOf('/') + 1).replace('_', ' '))));
+                                       qstring_to_ucs4(guiString(catsave.mid(catsave.indexOf('/') + 1)))));
                }
-               cat =  toqstr(translateIfPossible(qstring_to_ucs4(cat.replace('_', ' '))));
+               cat =  toqstr(translateIfPossible(qstring_to_ucs4(guiString(cat))));
                QTreeWidgetItem * catItem = new QTreeWidgetItem();
                if (!cats.contains(cat)) {
                        catItem->setText(0, cat);
@@ -364,14 +430,17 @@ void GuiLyXFiles::updateContents()
                QTreeWidgetItem * item = new QTreeWidgetItem();
                QString const filename = info.fileName();
                QString guiname = filename.left(filename.lastIndexOf(getSuffix())).replace('_', ' ');
-               if (translateName())
-                       guiname = toqstr(translateIfPossible(qstring_to_ucs4(guiname)));
-               QIcon file_icon = (info.filePath().startsWith(toqstr(package().user_support().absFileName()))) ?
+               // Special case: defaults.lyx
+               if (type_ == "templates" && guiname == "defaults")
+                       guiname = qt_("Default Template");
+               else if (translateName())
+                       guiname = toqstr(translateIfPossible(qstring_to_ucs4(guiString(guiname))));
+               QIcon file_icon = (realpath.startsWith(toqstr(package().user_support().absFileName()))) ?
                                user_icon : system_icon;
                item->setIcon(0, file_icon);
-               item->setData(0, Qt::UserRole, info.filePath());
+               item->setData(0, Qt::UserRole, it.key());
                item->setData(0, Qt::DisplayRole, guiname);
-               item->setData(0, Qt::ToolTipRole, info.filePath());
+               item->setData(0, Qt::ToolTipRole, realpath);
                if (subcat.isEmpty())
                        catItem->addChild(item);
                else {
@@ -438,13 +507,19 @@ void GuiLyXFiles::resetFilter()
        filterLabels();
 }
 
-QString const GuiLyXFiles::getRealPath()
+QString const GuiLyXFiles::getRealPath(QString relpath)
 {
-       QString const relpath = filesLW->currentItem()->data(0, Qt::UserRole).toString();
+       if (relpath.isEmpty())
+               relpath = filesLW->currentItem()->data(0, Qt::UserRole).toString();
        QString const language = languageCO->itemData(languageCO->currentIndex()).toString();
-       if (localizations_.contains(relpath)
-           && localizations_.find(relpath).value().contains(language))
-               return localizations_.find(relpath).value().find(language).value();
+       if (localizations_.contains(relpath)) {
+               if (localizations_.find(relpath).value().contains(language))
+                       return localizations_.find(relpath).value().find(language).value();
+               else if (localizations_.find(relpath).value().contains(guilang_))
+                       return localizations_.find(relpath).value().find(guilang_).value();
+               else if (localizations_.find(relpath).value().contains(toqstr("en")))
+                       return localizations_.find(relpath).value().find(toqstr("en")).value();
+       }
        return QString();
 }
 
@@ -469,22 +544,28 @@ bool GuiLyXFiles::initialiseParams(string const & type)
 }
 
 
+void GuiLyXFiles::passParams(string const & data)
+{
+       initialiseParams(data);
+       updateContents();
+}
+
+
+void GuiLyXFiles::selectItem(QString const item)
+{
+       /* Using an intermediary variable flags is needed up to at least
+        * Qt 5.5 because of a subtle namespace issue. See:
+        *   https://stackoverflow.com/questions/10755058/qflags-enum-type-conversion-fails-all-of-a-sudden
+        * for details.*/
+       Qt::MatchFlags const flags(Qt::MatchExactly|Qt::MatchRecursive);
+       QList<QTreeWidgetItem *> twi = filesLW->findItems(item, flags);
+       if (!twi.isEmpty())
+               twi.first()->setSelected(true);
+}
+
+
 void GuiLyXFiles::paramsToDialog()
 {
-       fileTypeCO->clear();
-       if (type_ == "examples" || type_ == "templates") {
-               fileTypeCO->addItem(qt_("Templates"), toqstr("templates"));
-               fileTypeCO->addItem(qt_("Examples"), toqstr("examples"));
-       } else if (type_ == "ui")
-               fileTypeCO->addItem(qt_("User Interface Files"), toqstr("ui"));
-       else if (type_ == "bind")
-               fileTypeCO->addItem(qt_("Key Binding Files"), toqstr("bind"));
-
-       if (!type_.isEmpty()) {
-               int i = fileTypeCO->findData(type_);
-               if (i != -1)
-                       fileTypeCO->setCurrentIndex(i);
-       }
        if (type_ == "examples")
                setTitle(qt_("Open Example File"));
        else if (type_ == "templates")
@@ -507,7 +588,11 @@ void GuiLyXFiles::dispatchParams()
        arg += fromqstr(file_);
        FuncCode const lfun = getLfun();
 
-       dispatch(FuncRequest(lfun, arg));
+       if (lfun == LFUN_NOACTION)
+               // emit signal
+               fileSelected(file_);
+       else
+               dispatch(FuncRequest(lfun, arg));
 }