]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/gnome/Menubar_pimpl.C
Clean-up of the button controller.
[lyx.git] / src / frontends / gnome / Menubar_pimpl.C
index 9135ad435c8686d3c38b8ab48131d260aab74d98..e5eb7d8c8ce3e52d5f7be174e4f3a414f4211c8a 100644 (file)
@@ -1,4 +1,3 @@
-// -*- C++ -*-
 /* This file is part of
  * ====================================================== 
  * 
 #include "LyXView.h"
 #include "MenuBackend.h"
 #include "Menubar_pimpl.h"
+#include "lyxtext.h"
+#include "exporter.h"
 
 #include "mainapp.h"
 
-using SigC::slot;
-using SigC::bind;
+#include <gtk--/menu.h>
 
 using std::endl;
 
@@ -41,6 +41,7 @@ using std::endl;
 extern GLyxAppWin * mainAppWin;
 
 // Some constants
+extern boost::scoped_ptr<kb_keymap> toplevel_keymap;
 extern LyXAction lyxaction;
 extern BufferList bufferlist;
 extern LastFiles * lastfiles; 
@@ -50,22 +51,27 @@ extern LastFiles * lastfiles;
 Menubar::Pimpl::Pimpl(LyXView * view, MenuBackend const & mb) 
   : owner_(view), menubackend_(&mb), ignore_action_(false)
 {
-       // Should we do something here?
+  
 }
 
 Menubar::Pimpl::~Pimpl() 
 {
-       // Should we do something here?
+  if (utoc_.connected()) utoc_.disconnect();
 }
 
 void Menubar::Pimpl::set(string const & menu_name) 
 {
   // if (current_menu_name_ != menu_name)  // disabled until Lastfiles and Documents are added dynamically to menu
-    {
+       //{
       current_menu_name_ = menu_name;
+
+      // clean up the lists
+      toc_.clear();
+      if (utoc_.connected()) utoc_.disconnect();
+      
       // compose new menu
       vector<Gnome::UI::Info> menus;
-      composeUIInfo(current_menu_name_, menus);
+      composeUIInfo(current_menu_name_, menus, "");
 
       // set menu
       Menu_ = menus;
@@ -79,9 +85,102 @@ void Menubar::Pimpl::set(string const & menu_name)
 
       // update state of the items
       update();
+      updateAllLists();
+      //}
+}
+
+void Menubar::Pimpl::updateAllLists()
+{
+#ifdef WITH_WARNINGS
+#warning Implement me! (be 20010324)
+#endif
+#if 0
+  // update lists
+  if (toc_.size() > 0)
+    {
+      vector<Buffer::TocItem> toclist = (owner_->view()->buffer()->getTocList())[Buffer::TOC_TOC];
+      updateList(&toclist, &toc_);
+    }
+#endif
+}
+
+int const max_number_of_items = 25;
+
+void Menubar::Pimpl::updateList(vector<Buffer::TocItem> * toclist, vector<ListsHolder> * pgui) 
+{
+  vector<ListsHolder> & gui = *pgui;
+  int szGui = gui.size();
+  int i;
+  for (i=0; i < szGui; ++i)
+    {
+      int oldsz = gui[i].lst.size();
+      vector<Gnome::UI::Info> menu;
+      string label;
+
+      menu.push_back(Gnome::UI::Item(Gnome::UI::Icon(GNOME_STOCK_MENU_REFRESH),
+                                    _("Refresh"), SigC::slot(this, &Menubar::Pimpl::updateAllLists)));
+
+      if (toclist->size() > max_number_of_items)
+       composeTocUIInfo(menu, *toclist, toclist->begin(), 0);
+      else
+       {
+         vector<Buffer::TocItem>::const_iterator end = toclist->end();
+         for (vector<Buffer::TocItem>::const_iterator it = toclist->begin();
+              it != end; ++it)
+           
+           {
+             label = string(4*(*it).depth,' ')+(*it).str;
+             
+             menu.push_back(Gnome::UI::Item(label,
+                                            SigC::bind<Buffer::TocItem>(SigC::slot(this, &Menubar::Pimpl::callbackToc), (*it)),
+                                            label));
+           }
+       }
+      
+      gui[i].lst = menu;
+      mainAppWin->update_menu(gui[i].path, oldsz, gui[i].lst);
     }
 }
 
+vector<Buffer::TocItem>::const_iterator
+Menubar::Pimpl::composeTocUIInfo(vector<Gnome::UI::Info> & menu,
+                                vector<Buffer::TocItem> const & toclist,
+                                vector<Buffer::TocItem>::const_iterator begin,
+                                int mylevel)
+{
+  string label = _("<No Name>");
+
+  vector<Buffer::TocItem>::const_iterator end = toclist.end();
+  vector<Buffer::TocItem>::const_iterator it;
+  for (it = begin; it != end && (*it).depth >= mylevel; ++it)
+    {
+      if ( (*it).depth == mylevel &&
+          (it+1 == end || (*(it+1)).depth <= mylevel) )
+       {
+         label = (*it).str;
+         menu.push_back(Gnome::UI::Item(label,
+                                      SigC::bind<Buffer::TocItem>(SigC::slot(this, &Menubar::Pimpl::callbackToc), (*it)),
+                                        label));
+       }
+      else
+       {
+         vector<Gnome::UI::Info> submenu;
+         if ( (*it).depth == mylevel )
+           {
+             label = (*it).str;
+             submenu.push_back(Gnome::UI::Item(label,
+                                               SigC::bind<Buffer::TocItem>(SigC::slot(this, &Menubar::Pimpl::callbackToc), (*it)),
+                                               label));
+             ++it;    
+           }
+         it = composeTocUIInfo(submenu, toclist, it, mylevel+1);
+         menu.push_back(Gnome::UI::Menu(label,submenu,label));
+       }
+    }
+  --it;
+  return it;
+}
+
 void Menubar::Pimpl::callback(int action)
 {
   // Dispatch action OR record action to local variable (see connectWidgetToAction)
@@ -92,8 +191,24 @@ void Menubar::Pimpl::callback(int action)
       action_ = action;
 }
 
-void Menubar::Pimpl::composeUIInfo(string const & menu_name, vector<Gnome::UI::Info> & Menus)
+void Menubar::Pimpl::callbackToc(Buffer::TocItem tg)
 {
+#if 0 
+  if (!owner_->view()->available()) return;
+  
+  owner_->view()->beforeChange();
+  owner_->view()->text->SetCursor( owner_->view(), tg.par, 0 );
+  owner_->view()->text->sel_cursor = owner_->view()->text->cursor;
+  owner_->view()->update(BufferView::SELECT|BufferView::FITCUR);
+#endif
+
+  owner_->getLyXFunc()->Dispatch(LFUN_GOTO_PARAGRAPH, tg.str);
+}
+
+void Menubar::Pimpl::composeUIInfo(string const & menu_name, vector<Gnome::UI::Info> & Menus, string rootpath)
+{
+  string path = rootpath;
+    
   if (!menubackend_->hasMenu(menu_name))
     {
       cout << "ERROR:composeUIInfo: Unknown menu `" << menu_name
@@ -101,7 +216,8 @@ void Menubar::Pimpl::composeUIInfo(string const & menu_name, vector<Gnome::UI::I
       return;
     }
 
-  Menu menu = menubackend_->getMenu(menu_name);
+  Menu menu = Menu();
+  menubackend_->getMenu(menu_name).expand(menu, owner_->buffer());
 
   for (Menu::const_iterator i = menu.begin(); i != menu.end(); ++i)
     {
@@ -110,45 +226,84 @@ void Menubar::Pimpl::composeUIInfo(string const & menu_name, vector<Gnome::UI::I
 
       case MenuItem::Command: {
        string label = item.label();
+
+       path = rootpath + label;
+       
        if (label.find(item.shortcut()) != string::npos)
          label.insert(label.find(item.shortcut()), "_");
 
        LyXFunc::func_status flag = owner_->getLyXFunc()->getStatus(item.action());
 
        Gnome::UI::Info gitem;
-       SigC::Slot0<void> cback = bind<int>(slot(this, &Menubar::Pimpl::callback),item.action());
+       SigC::Slot0<void> cback = SigC::bind<int>(SigC::slot(this, &Menubar::Pimpl::callback),item.action());
 
        {
          using namespace Gnome::MenuItems;
-         string actionname = lyxaction.getActionName(item.action());
-         if ( actionname ==  "buffer-open") gitem = Open(cback);
-         else if ( actionname ==  "lyx-quit") gitem = Exit(cback);
-         else if ( actionname ==  "buffer-close") gitem = Close(cback);
-         else if ( actionname ==  "buffer-write") gitem = Save(cback);
-         else if ( actionname ==  "buffer-write-as") gitem = SaveAs(cback);
-         else if ( actionname ==  "buffer-print") gitem = Print(cback);
-         else if ( actionname ==  "cut") gitem = Cut(cback);
-         else if ( actionname ==  "copy") gitem = Copy(cback);
-         else if ( actionname ==  "paste") gitem = Paste(cback);
-         else if ( actionname ==  "undo") gitem = Gnome::MenuItems::Undo(cback); // confused with class Undo
-         else if ( actionname ==  "redo") gitem = Redo(cback);
-         else if ( actionname ==  "dialog-preferences") gitem = Preferences(cback);
-         else if ( actionname ==  "buffer-new")
+         int ac = item.action();
+         kb_action action;
+         string argument;
+         if (lyxaction.isPseudoAction(ac))
+           action = lyxaction.retrieveActionArg(ac, argument);
+         else
+           action = static_cast<kb_action>(ac);
+
+         switch(action) {
+         case LFUN_FILE_OPEN:
+           gitem = Open(cback);
+           break;
+         case LFUN_QUIT:
+           gitem = Exit(cback);
+           break;
+         case LFUN_CLOSEBUFFER:
+           gitem = Close(cback);
+           break;
+         case LFUN_MENUWRITE:
+           gitem = Save(cback);
+           break;
+         case LFUN_WRITEAS:
+           gitem = SaveAs(cback);
+           break;
+         case LFUN_BUFFER_PRINT:
+           gitem = Print(cback);
+           break;
+         case LFUN_CUT:
+           gitem = Cut(cback);
+           break;
+         case LFUN_COPY:
+           gitem = Copy(cback);
+           break;
+         case LFUN_PASTE:
+           gitem = Paste(cback);
+           break;
+         case LFUN_UNDO:
+           gitem = Gnome::MenuItems::Undo(cback); // confused with class Undo
+           break;
+         case LFUN_REDO:
+           gitem = Redo(cback);
+           break;
+         case LFUN_DIALOG_PREFERENCES:
+           gitem = Preferences(cback);
+           break;
+         case LFUN_MENUNEW:
            gitem = Gnome::UI::Item(Gnome::UI::Icon(GNOME_STOCK_MENU_NEW),
                                    label, cback, lyxaction.helpText(item.action()));
-         else if ( actionname ==  "buffer-new-template")
+           break;
+         case LFUN_MENUNEWTMPLT:
            gitem = Gnome::UI::Item(Gnome::UI::Icon(GNOME_STOCK_MENU_NEW), 
                                    label, cback, lyxaction.helpText(item.action()));
-         else if ( actionname ==  "find-replace" )
+           break;
+         case LFUN_MENUSEARCH:
            gitem = Gnome::UI::Item(Gnome::UI::Icon(GNOME_STOCK_MENU_SRCHRPL), 
                                    label, cback, lyxaction.helpText(item.action()));
-         else if ( actionname ==  "spellchecker" )
+           break;
+         case LFUN_SPELLCHECK:
            gitem = Gnome::UI::Item(Gnome::UI::Icon(GNOME_STOCK_MENU_SPELLCHECK), 
                                    label, cback, lyxaction.helpText(item.action()));
-//       else if ( actionname ==  "" )
-//         gitem = Gnome::UI::Item(Gnome::UI::Icon(), 
-//                                 label, cback, lyxaction.helpText(item.action()));
-         else gitem = Gnome::UI::Item(label, cback, lyxaction.helpText(item.action()));
+           break;
+         default:
+           gitem = Gnome::UI::Item(label, cback, lyxaction.helpText(item.action()));
+           break;
+         }
        }
 
        // first handle optional entries.
@@ -159,7 +314,7 @@ void Menubar::Pimpl::composeUIInfo(string const & menu_name, vector<Gnome::UI::I
        }
        if ((flag & LyXFunc::ToggleOn) || (flag & LyXFunc::ToggleOff))
          gitem = Gnome::UI::ToggleItem(label, cback, lyxaction.helpText(item.action()));
-       
+
        Menus.push_back(gitem);
        break;
       }
@@ -167,49 +322,39 @@ void Menubar::Pimpl::composeUIInfo(string const & menu_name, vector<Gnome::UI::I
       case MenuItem::Submenu: {
        vector<Gnome::UI::Info> submenu;
        string label = item.label();
+
+       path = rootpath + label;
+       
        if (label.find(item.shortcut()) != string::npos)
          label.insert(label.find(item.shortcut()), "_");
-       composeUIInfo(item.submenu(), submenu);
+       composeUIInfo(item.submenu(), submenu, path + "/");
        Menus.push_back(Gnome::UI::Menu(label,submenu,label));
        break;
       }
 
       case MenuItem::Separator: {
+
+       path = rootpath + "<Separator>";
+       
        Menus.push_back(Gnome::UI::Separator());
        break;
       }
 
-      case MenuItem::Lastfiles: {
-       int ii = 1;
-       for (LastFiles::const_iterator cit = lastfiles->begin();
-            cit != lastfiles->end() && ii < 10; ++cit, ++ii)
-         {
-           int action = lyxaction.getPseudoAction(LFUN_FILE_OPEN, (*cit));
-           string label = "_" + tostr(ii) + ". " + MakeDisplayPath((*cit),30);
-
-           Menus.push_back(Gnome::UI::Item(label,
-                                           bind<int>(slot(this, &Menubar::Pimpl::callback), action),
-                                           label));
-         }
+      case MenuItem::Toc: {
+       ListsHolder t;
+       t.path = path;
+       toc_.push_back(t);
        break;
       }
       
-      case MenuItem::Documents: {
-       std::vector<string> names = bufferlist.getFileNames();
-
-       for (std::vector<string>::const_iterator cit = names.begin();
-            cit != names.end() ; ++cit)
-         {
-           int action = lyxaction.getPseudoAction(LFUN_SWITCHBUFFER, *cit);
-           string label = MakeDisplayPath(*cit, 30);
-
-           Menus.push_back(Gnome::UI::Item(label,
-                                           bind<int>(slot(this, &Menubar::Pimpl::callback), action),
-                                           label));
-           
-         }
-       break;
-      }
+      case MenuItem::Documents: 
+      case MenuItem::Lastfiles: 
+      case MenuItem::ViewFormats:
+      case MenuItem::UpdateFormats:
+      case MenuItem::ExportFormats:
+                       lyxerr << "Menubar::Pimpl::create_submenu: "
+                         "this should not happen" << endl;
+                       break;
       }
     }
 }
@@ -218,10 +363,11 @@ void Menubar::Pimpl::connectWidgetToAction(GnomeUIInfo * guinfo)
 {
   for (; guinfo->type !=  GnomeUIInfoType(GNOME_APP_UI_ENDOFINFO); ++guinfo)
     {
-      if ( guinfo->type == GnomeUIInfoType(GNOME_APP_UI_ITEM) ||
-          guinfo->type == GnomeUIInfoType(GNOME_APP_UI_TOGGLEITEM) )
+      if ( ( guinfo->type == GnomeUIInfoType(GNOME_APP_UI_ITEM) ||
+            guinfo->type == GnomeUIInfoType(GNOME_APP_UI_TOGGLEITEM) ) &&
+          guinfo->moreinfo != 0 )
        {
-         (*((void(*)(void *, void *))(guinfo->moreinfo)))(NULL, guinfo->user_data);
+         (*((void(*)(void *, void *))(guinfo->moreinfo)))(0, guinfo->user_data);
          wid_act_.push_back( GtkWidgetToAction( guinfo->widget, action_ ) );
        }
       else if ( guinfo->type == GnomeUIInfoType(GNOME_APP_UI_SUBTREE) ||
@@ -259,7 +405,7 @@ void Menubar::Pimpl::update()
     }
 }
 
-void Menubar::Pimpl::openByName(string const & name)
+void Menubar::Pimpl::openByName(string const &)
 {
 //    Pimpl::update();
 }