]> git.lyx.org Git - lyx.git/blobdiff - src/filedlg.C
More fixes to insettabular/text (and some missing features added).
[lyx.git] / src / filedlg.C
index 043e17ca97faca83c7bcaca700789375f17caa69..2b6949034aca2fe0d77ff25169b6e593bbee7622 100644 (file)
 #include <cstring>
 #include <map>
 #include <algorithm>
+
 using std::map;
+using std::max;
 using std::sort;
 
 #include "lyx_gui_misc.h" // CancelCloseCB
 #include "support/FileInfo.h"
+#include "support/lyxlib.h"
 #include "gettext.h"
+#include "frontends/Dialogs.h"
 
 #ifdef HAVE_ERRNO_H
 #include <cerrno>
@@ -59,7 +63,6 @@ using std::sort;
 
 #ifdef BROKEN_HEADERS
 extern "C" int gettimeofday(struct timeval *, struct timezone *);
-#define remove(a) unlink(a)      
 #endif
 
 #ifdef __GNUG__
@@ -69,6 +72,10 @@ extern "C" int gettimeofday(struct timeval *, struct timezone *);
 #include "support/filetools.h"
 #include "filedlg.h"
 
+#ifdef SIGC_CXX_NAMESPACES
+using SigC::slot;
+#endif
+
 // six months, in seconds
 static const long SIX_MONTH_SEC = 6L * 30L * 24L * 60L * 60L;
 static const long ONE_HOUR_SEC = 60L * 60L;
@@ -88,20 +95,7 @@ public:
        }
 private:
        ///
-       void add(uid_t ID) const {
-               string pszNewName;
-               struct passwd * pEntry;
-               
-               // gets user name
-               if ((pEntry = getpwuid(ID)))
-                       pszNewName = pEntry->pw_name;
-               else {
-                       pszNewName = tostr(ID);
-               }
-               
-               // adds new node
-               users[ID] = pszNewName;
-       }
+       void add(uid_t ID) const;
        ///
        typedef map<uid_t, string> Users;
        ///
@@ -109,42 +103,69 @@ private:
 };
 
 
+void UserCache::add(uid_t ID) const 
+{
+       string pszNewName;
+       struct passwd * pEntry;
+       
+       // gets user name
+       if ((pEntry = getpwuid(ID)))
+               pszNewName = pEntry->pw_name;
+       else {
+               pszNewName = tostr(ID);
+       }
+       
+       // adds new node
+       users[ID] = pszNewName;
+}      
+
+
 /// Group cache class definition
 class GroupCache {
 public:
        /// seeks group name from group ID
-       string const & find(gid_t ID) const {
-               Groups::const_iterator cit = groups.find(ID);
-               if (cit == groups.end()) {
-                       add(ID);
-                       return groups[ID];
-               }
-               return (*cit).second;
-       }
+       string const & find(gid_t ID) const ;
 private:
        ///
-       void add(gid_t ID) const {
-               string pszNewName;
-               struct group * pEntry;
-               
-               // gets user name
-               if ((pEntry = getgrgid(ID))) pszNewName = pEntry->gr_name;
-               else {
-                       pszNewName = tostr(ID);
-               }
-               // adds new node
-               groups[ID] = pszNewName;
-       }
+       void add(gid_t ID) const;
        ///
        typedef map<gid_t, string> Groups;
        ///
        mutable Groups groups;
 };
 
+
+string const & GroupCache::find(gid_t ID) const 
+{
+       Groups::const_iterator cit = groups.find(ID);
+       if (cit == groups.end()) {
+               add(ID);
+               return groups[ID];
+       }
+       return (*cit).second;
+}
+
+
+void GroupCache::add(gid_t ID) const 
+{
+       string pszNewName;
+       struct group * pEntry;
+       
+       // gets user name
+       if ((pEntry = getgrgid(ID))) pszNewName = pEntry->gr_name;
+       else {
+               pszNewName = tostr(ID);
+       }
+       // adds new node
+       groups[ID] = pszNewName;
+}
+
+
 // static instances
 static UserCache lyxUserCache;
 static GroupCache lyxGroupCache;
 
+
 // some "C" wrappers around callbacks
 extern "C" void C_LyXFileDlg_FileDlgCB(FL_OBJECT *, long lArgument);
 extern "C" void C_LyXFileDlg_DoubleClickCB(FL_OBJECT *, long);
@@ -155,6 +176,9 @@ extern "C" int C_LyXFileDlg_CancelCB(FL_FORM *, void *);
 class comp_direntry {
 public:
        int operator()(LyXDirEntry const & r1,
+                      LyXDirEntry const & r2) const ;
+};
+       int comp_direntry::operator()(LyXDirEntry const & r1,
                       LyXDirEntry const & r2) const {
                bool r1d = suffixIs(r1.pszName, '/');
                bool r2d = suffixIs(r2.pszName, '/');
@@ -162,7 +186,6 @@ public:
                if (!r1d && r2d) return 0;
                return r1.pszName < r2.pszName;
        }
-};
 
 
 // *** LyXFileDlg class implementation
@@ -176,12 +199,12 @@ LyXFileDlg * LyXFileDlg::pCurrentDlg = 0;
 void LyXFileDlg::Reread()
 {
        // Opens directory
-       DIR * pDirectory = opendir(pszDirectory.c_str());
+       DIR * pDirectory = ::opendir(pszDirectory.c_str());
        if (!pDirectory) {
                WriteFSAlert(_("Warning! Couldn't open directory."), 
                             pszDirectory);
-               pszDirectory = GetCWD();
-               pDirectory = opendir(pszDirectory.c_str());
+               pszDirectory = lyx::getcwd();
+               pDirectory = ::opendir(pszDirectory.c_str());
        }
 
        // Clear the present namelist
@@ -319,7 +342,7 @@ void LyXFileDlg::Reread()
        // Add them to directory box
        for (DirEntries::const_iterator cit = direntries.begin();
             cit != direntries.end(); ++cit) {
-               string temp = line + (*cit).pszDisplayed;
+               string const temp = line + (*cit).pszDisplayed;
                fl_add_browser_line(pFileDlgForm->List, temp.c_str());
        }
        fl_set_browser_topline(pFileDlgForm->List, iDepth);
@@ -391,6 +414,21 @@ LyXFileDlg::LyXFileDlg()
        }
        fl_hide_object(pFileDlgForm->User1);
        fl_hide_object(pFileDlgForm->User2);
+
+       r_ = Dialogs::redrawGUI.connect(slot(this, &LyXFileDlg::redraw));
+}
+
+
+LyXFileDlg::~LyXFileDlg()
+{
+       r_.disconnect();
+}
+
+
+void LyXFileDlg::redraw()
+{
+       if (pFileDlgForm->FileDlg && pFileDlgForm->FileDlg->visible)
+               fl_redraw_form(pFileDlgForm->FileDlg);
 }
 
 
@@ -415,13 +453,13 @@ void LyXFileDlg::SetButton(int iIndex, string const & pszName,
                *pTemp = pszPath;
        } else {
                fl_hide_object(pObject);
-               (*pTemp).clear();
+               (*pTemp).erase();
        }
 }
 
 
 // GetDirectory: gets last dialog directory
-string LyXFileDlg::GetDirectory() const
+string const LyXFileDlg::GetDirectory() const
 {
        if (!pszDirectory.empty())
                return pszDirectory;
@@ -438,7 +476,6 @@ bool LyXFileDlg::RunDialog()
        
         // event loop
         while(true) {
-
                 FL_OBJECT * pObject = fl_do_forms();
 
                 if (pObject == pFileDlgForm->Ready) {
@@ -507,6 +544,7 @@ void LyXFileDlg::FileDlgCB(FL_OBJECT *, long lArgument)
        }
 }
 
+
 extern "C" void C_LyXFileDlg_FileDlgCB(FL_OBJECT * ob, long data) 
 {
        LyXFileDlg::FileDlgCB(ob, data);
@@ -517,7 +555,7 @@ extern "C" void C_LyXFileDlg_FileDlgCB(FL_OBJECT * ob, long data)
 void LyXFileDlg::HandleListHit()
 {
        // set info line
-       int iSelect = fl_get_browser(pFileDlgForm->List);
+       int const iSelect = fl_get_browser(pFileDlgForm->List);
        if (iSelect > iDepth)  {
                SetInfoLine(direntries[iSelect - iDepth - 1].pszLsEntry);
        } else {
@@ -534,11 +572,13 @@ void LyXFileDlg::DoubleClickCB(FL_OBJECT *, long)
                pCurrentDlg->Force(false);
 }
 
+
 extern "C" void C_LyXFileDlg_DoubleClickCB(FL_OBJECT * ob, long data)
 {
        LyXFileDlg::DoubleClickCB(ob, data);
 }
 
+
 // Handle double click from list
 bool LyXFileDlg::HandleDoubleClick()
 {
@@ -546,7 +586,7 @@ bool LyXFileDlg::HandleDoubleClick()
 
        // set info line
        bool isDir = true;
-       int iSelect = fl_get_browser(pFileDlgForm->List);
+       int const iSelect = fl_get_browser(pFileDlgForm->List);
        if (iSelect > iDepth)  {
                pszTemp = direntries[iSelect - iDepth - 1].pszName;
                SetInfoLine(direntries[iSelect - iDepth - 1].pszLsEntry);
@@ -573,7 +613,7 @@ bool LyXFileDlg::HandleDoubleClick()
                        Temp += pszTemp;
                } else {
                        // Directory higher up
-                       Temp.clear();
+                       Temp.erase();
                        for (int i = 0; i < iSelect; ++i) {
                                string piece = fl_get_browser_line(pFileDlgForm->List, i+1);
                                // The '+2' is here to count the '@b' (JMarc)
@@ -595,7 +635,7 @@ bool LyXFileDlg::HandleOK()
 {
        // mask was changed
        string pszTemp = fl_get_input(pFileDlgForm->PatBox);
-       if (pszTemp!= pszMask) {
+       if (pszTemp != pszMask) {
                SetMask(pszTemp);
                Reread();
                return false;
@@ -610,19 +650,20 @@ bool LyXFileDlg::HandleOK()
        }
        
        // Handle return from list
-       int select = fl_get_browser(pFileDlgForm->List);
+       int const select = fl_get_browser(pFileDlgForm->List);
        if (select > iDepth) {
-               string temp = direntries[select - iDepth - 1].pszName;
+               string const temp = direntries[select - iDepth - 1].pszName;
                if (!suffixIs(temp, '/')) {
                        // If user didn't type anything, use browser
-                       string name = fl_get_input(pFileDlgForm->Filename);
+                       string const name =
+                               fl_get_input(pFileDlgForm->Filename);
                        if (name.empty()) {
                                fl_set_input(pFileDlgForm->Filename, temp.c_str());
                        }
                        return true;
                }
        }
-       
+
        // Emulate a doubleclick
        return HandleDoubleClick();
 }
@@ -659,8 +700,8 @@ void LyXFileDlg::Force(bool cancel)
 
 
 // Select: launches dialog and returns selected file
-string LyXFileDlg::Select(string const & title, string const & path, 
-                         string const & mask, string const & suggested)
+string const LyXFileDlg::Select(string const & title, string const & path, 
+                               string const & mask, string const & suggested)
 {
        // handles new mask and path
        bool isOk = true;
@@ -673,27 +714,44 @@ string LyXFileDlg::Select(string const & title, string const & path,
                isOk = false;
        }
        if (!isOk) Reread();
-       else {
-               fl_select_browser_line(pFileDlgForm->List, 1);
-               fl_set_browser_topline(pFileDlgForm->List, 1);
+
+       // highlight the suggested file in the browser, if it exists.
+       int sel = 0;
+       string const filename = OnlyFilename(suggested);
+       if (!filename.empty()) {
+               for (int i = 0; 
+                    i < fl_get_browser_maxline(pFileDlgForm->List); ++i) {
+                       string s =
+                               fl_get_browser_line(pFileDlgForm->List, i + 1);
+                       s = strip(frontStrip(s));
+                       if (s == filename) {
+                               sel = i + 1;
+                               break;
+                       }
+               }
        }
+       
+       if (sel != 0) fl_select_browser_line(pFileDlgForm->List, sel);
+       int const top = max(sel - 5, 1);
+       fl_set_browser_topline(pFileDlgForm->List, top);
 
        // checks whether dialog can be started
        if (pCurrentDlg) return string();
        pCurrentDlg = this;
 
        // runs dialog
-       SetInfoLine (string());
+       SetInfoLine(string());
        fl_set_input(pFileDlgForm->Filename, suggested.c_str());
        fl_set_button(pFileDlgForm->Cancel, 0);
        fl_set_button(pFileDlgForm->Ready, 0);
        fl_set_focus_object(pFileDlgForm->FileDlg, pFileDlgForm->Filename);
        fl_deactivate_all_forms();
-       fl_show_form(pFileDlgForm->FileDlg, FL_PLACE_MOUSE | FL_FREE_SIZE,
-                    FL_FULLBORDER, title.c_str());
+       fl_show_form(pFileDlgForm->FileDlg, 
+                    FL_PLACE_MOUSE | FL_FREE_SIZE, FL_TRANSIENT,
+                    title.c_str());
 
        isOk = RunDialog();
-
+       
        fl_hide_form(pFileDlgForm->FileDlg);
        fl_activate_all_forms();
        pCurrentDlg = 0;