Подключить ленту из cuix

Автор Тема: Подключить ленту из cuix  (Прочитано 11403 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 166
    • Мои плагины к Автокаду
Подключить ленту из cuix
« : 26-03-2021, 13:28:41 »
Наверно все сталкивались с ситуацией, когда Автокад упорно не показывает ленты (Ribbon) из CUIX плагина. Устал помогать пользователям решать эту проблему. Вот поставил себе 2022 - и опять эта проблема.
Обычно это происходит при установке нового Автокад или нового плагина или новой версии старого плагина. В списке файлов частичной кастомизации мой cuix присутствует, панели инструментов нарисовались (хотя включен ленточный интерфейс, зачем панели-то?). А лента Add-ins пуста и других самодельных лент тоже нет. Причем их нет даже в списке выключенных. Можно почистить папку support и перезагрузить Автокад несколько раз, покликать workspace-ами, чтоб ленты все-таки нарисовались. Но может есть какой-то программный способ включить риббонки? Я уже сделал код, который грузит CUIX, если он еще не загружен. Но тут другой случай, мой cuix уже есть в CustomizationSection.PartialCuiFiles

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 546
  • Карма: 119
Re: Подключить ленту из cuix
« Ответ #1 : 26-03-2021, 14:02:43 »
хотя включен ленточный интерфейс, зачем панели-то?
Ленточный интерфейс не отключает панели, меню и т.д. Он как-бы дополнение к уже имеющимся.

А лента Add-ins пуста и других самодельных лент тоже нет.
Частенько связано с рабочими пространствами. Т.е. вроде должно появиться, но нет. Обычно приходится заходить в адаптацию рабочего пространства и настраивать руками.
И, если не путаю, то меню и панели появляются автоматом. А с лентой и панелью быстрого доступа приходится дополнительно настраивать.
Если частичный CUIX уже был подгружен в основной CUIX то иногда приходиться выгружать/загружать частичный CUIX или даже заменять основной.

Но может есть какой-то программный способ включить риббонки?
Не знаю как программно, не требовалось.
Можно сделать настройки в основном файле адаптации и частичном. И после подгрузки лента должна добавиться в текущее рабочее пространство.

В настройках вкладки ленты нужно выставить настройки
Добавить к рабочим пространствам
Объединять или добавлять вкладку

И что не очевидно, нужно задать Псевдонимы

Из справки:
Отображение вкладок ленты из частичного файла CUIx
При загрузке вкладок ленты из частичного файла CUIx свойство "Поведение рабочего пространства" можно использовать для управления способом обработки вкладок ленты, которые, возможно, используют один и тот же псевдоним в главном и в частичном файлах CUIx. Опция "Только добавлять вкладку" приводит к отображению каждой вкладки ленты, загружаемой с рабочим пространством, как вкладки этого рабочего пространства. А опция "Только объединять вкладку" приводит к отображению вкладок ленты из частичного файла CUIx только при наличии для них соответствующих псевдонимов в главном файле CUIx. Опция "Объединять или добавлять вкладку" приводит к объединению вкладки прежде, чем на ленте будет создана новая вкладка.


Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 166
    • Мои плагины к Автокаду
Re: Подключить ленту из cuix
« Ответ #2 : 26-03-2021, 14:32:16 »
иногда приходиться выгружать/загружать частичный CUIX или даже заменять основной.
Да, приходится выгружать/загружать. И учить этому всех пользователей. Могу выгрузить программно, но как узнать что это надо сделать, что лента не отображена?
В свойствах всех Tabs задано "Merge or add tab"
А вот алиасы у табов и панелей как попало - где-то не задал, где-то одинаковые. Не знал где они вообще используются. Попробовал подправить. Задал всем уникальные псевдонимы. Ничего не изменилось.

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 546
  • Карма: 119
Re: Подключить ленту из cuix
« Ответ #3 : 26-03-2021, 14:49:37 »
Попробую подправить, но сильно сомневаюсь что проблема из-за этого.
Проблема не из-за этого, это если хочешь чтобы вкладки подгрузились в рабочее пространство, при подгрузке CUIX, то придется задать одинаковые алиасы в  основном и частичном файле.
Иначе механизм не сработает.

Проблемы из-за настроек отображения в самих рабочих пространствах.
Под каждым рабочим пространством ты указываешь какие вкладки ленты отображать, какие скрыть и в какой последовательности.

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 166
    • Мои плагины к Автокаду
Re: Подключить ленту из cuix
« Ответ #4 : 31-03-2021, 13:37:36 »
Итого. Чтоб просто проверить, загружены ли мои ленты в текущий workspace пришлось изобрести вот такого крокозябра:
Код - C# [Выбрать]
  1.     /// <summary>
  2.     /// загрузка CUIX если его еще нет в загруженных. проверяет обновление файла. проверяет, что загрузились ленты
  3.     /// </summary>
  4.     internal static void LoadMenu(string pluginPath, string pluginName)
  5.     {
  6.         string myCuiName = pluginName + ".cuix";
  7.         string myCuiFile = Path.Combine(pluginPath, myCuiName);
  8.         if (!File.Exists(myCuiFile))
  9.           return;
  10.  
  11.         string mainCuiFile = Application.GetSystemVariable("MENUNAME") + ".cuix";
  12.         if (!File.Exists(mainCuiFile)) //  бывает и так
  13.           return;
  14.  
  15.         CustomizationSection mainCui = new(mainCuiFile);
  16.         if (mainCui is null) return;
  17.         PartialCuiFileCollection partialFiles = mainCui.PartialCuiFiles;
  18.         if (partialFiles.Contains(myCuiName)) //мой Cuix уже загружен
  19.         {
  20.           // проверим, что мой новейший cuix скопирован из папки плагина в папку support
  21.           FileInfo myInf = new(myCuiFile);
  22.           FileInfo mainInf = new(mainCuiFile);
  23.           if (myInf.LastWriteTime > mainInf.LastWriteTime) // не 100% гарантия, но на практике можно и так проверить
  24.           {
  25.             mainCui.RemovePartialMenu(myCuiName, pluginName); // выгрузка, чтоб потом сразу опять загрузить
  26.             if (mainCui.IsModified) mainCui.Save();
  27.           }
  28.           else // с версией все хорошо, но проверим еще, что видны ленты или ленточные панели из моего cuix
  29.           {
  30.             //if ((Int16)Application.GetSystemVariable("RIBBONSTATE") == 0) return; всегда 0 если вызывать из InitializationPlugin
  31.             string wsname = (string)Application.GetSystemVariable("WSCURRENT");
  32.             if (IsNullOrEmpty(wsname)) return;
  33.             Workspace ws = mainCui.getWorkspace(wsname);
  34.             HashSet<string> paneles = AllRibbonPanels(ws.WorkspaceRibbonRoot); // все панели всех лент главного CUI
  35.             CustomizationSection myCui = new(myCuiFile);
  36.             RibbonRoot root = myCui.MenuGroup?.RibbonRoot;
  37.             if (root is null) return;
  38.             bool loaded = false;
  39.             foreach (RibbonTabSource myTab in root.RibbonTabSources)
  40.             {
  41.               //if (cs.LookupElement(myTab.ElementID) is not null) // так не работает - ElementID меняется при подключении к главному cui
  42.               //{ loaded = true; break; }
  43.               if (ws.WorkspaceRibbonRoot.FindTabReference(myCui.MenuGroup.Name, myTab.ElementID) is not null)
  44.               { loaded = true; break; } // нашли одну из лент из моего cuix
  45.               foreach (RibbonPanelSourceReference panel in myTab.Items)
  46.                 if (paneles.Contains(myCui.MenuGroup.Name + '.' + panel.PanelId)) // панели из частичного cui имеют составные Id
  47.                 { loaded = true; break; }
  48.               if (loaded) break; // нашли одну из панелей из моего cuix на ленте Add-ins
  49.             }
  50.             if (!loaded) // cuix загрузился, но панели в текущем пространстве не подключились
  51.             {
  52.               mainCui.RemovePartialMenu(myCuiName, pluginName);
  53.               if (mainCui.IsModified) mainCui.Save();
  54.             }
  55.             else
  56.               return;
  57.           }
  58.         }
  59.  
  60.         // мой cuix не загружен или пришлось выгрузить
  61.         if (mainCui.AddPartialMenu(myCuiFile))
  62.         {
  63.           if (mainCui.IsModified)
  64.           {
  65.             mainCui.Save();
  66.             Application.ReloadAllMenus();
  67.           }
  68.         }
  69.     }
  70.  
  71.     /// <summary>
  72.     /// Идентификаторы всех панелей всех лент
  73.     /// </summary>
  74.     static HashSet<string> AllRibbonPanels(WSRibbonRoot root)
  75.     {
  76.       HashSet<string> ret = new();
  77.       if (root is not null)
  78.         foreach (WSRibbonTabSourceReference tab in root.WorkspaceTabs)
  79.           foreach (WSRibbonPanelSourceReference panel in tab.Panels)
  80.             if (!ret.Contains(panel.PanelId))
  81.               ret.Add(panel.PanelId);
  82.       return ret;
  83.     }
Есть большие сомнения, что способ оптимальный. Но работает.
Точно такая же проблема есть и с загрузкой менюшки в классическом интерфейсе - надо бы отдельно запрограммировать проверку.
Не удалось понять включена ли лента. У workspace есть свойство MenuBar, но потерялось Ribbon.
Странно, что все элементы API не имеют ни имени, ни описания. Искать приходится только по Id. В результате я не могу найти ленту Add-ins. У нее странный цифровой Id в отличии от остальных стандартных лент. Скорее всего будет разным в разных версиях. Приходится перебирать вообще все все ленты.
Можно было вообще не парится, а просто перезагружать мой cuix при каждой инициализации плагина - задержка не особо заметная.
p.s.
написано для 2013 для совместимости. Возможно в более новых Автокадах это API стало более человечным.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Подключить ленту из cuix
« Ответ #5 : 31-03-2021, 13:54:31 »
Не удалось понять включена ли лента. У workspace есть свойство MenuBar, но потерялось Ribbon.
Код - C# [Выбрать]
  1.             RibbonControl ribbon = ComponentManager.Ribbon;
  2.             if (ribbon != null)
  3.             {
  4.               //  лента включена
  5.             }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 166
    • Мои плагины к Автокаду
Re: Подключить ленту из cuix
« Ответ #6 : 31-03-2021, 14:04:02 »
ComponentManager - это из какого namespace? похоже нет его в API 2013

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Подключить ленту из cuix
« Ответ #7 : 31-03-2021, 14:35:41 »
ComponentManager - это из какого namespace? похоже нет его в API 2013
Autodesk.Windows.ComponentManager (из AdWindows.dll) - есть в 2013
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 166
    • Мои плагины к Автокаду
Re: Подключить ленту из cuix
« Ответ #8 : 31-03-2021, 15:16:46 »
Не. Так тоже не получится. ComponentManager.Ribbon == null пока идет инициализация плагина. Команда Ribbon вызывается позже. Задача в том , чтоб у Workspace узнать - будет в нем открываться лента или нет.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Подключить ленту из cuix
« Ответ #9 : 31-03-2021, 15:30:01 »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 166
    • Мои плагины к Автокаду
Re: Подключить ленту из cuix
« Ответ #10 : 31-03-2021, 15:43:14 »
Ribbonstate само собой всегда 0. Лента ж не открыта еще. Я об это в коде написал - закомментированная строка.
Но в общем-то это не главная проблема. Ну будет перезагружаться cuix, даже у тех кто до сих пор в классическом интерфейсе. Это не беда.
Просто вызвало удивление недоделанное API. Вдруг где-то запрятано что-то вроде Workspace.ShowRibbon, а я его в упор не вижу.
Так же как и WSRibbonTabSourceReference.Name или DisplayName - должен же быть, но его нет.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Подключить ленту из cuix
« Ответ #11 : 31-03-2021, 15:56:28 »
Ribbonstate само собой всегда 0. Лента ж не открыта еще.
Так чего же его проверять в Initialize(), если можно проверить когда ComponentManager.Ribbon != null
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Привалов Дмитрий

  • ADN Club
  • *****
  • Сообщений: 546
  • Карма: 119
Re: Подключить ленту из cuix
« Ответ #12 : 31-03-2021, 15:59:38 »
Можно было вообще не парится, а просто перезагружать мой cuix при каждой инициализации плагина - задержка не особо заметная.
Перезагружать зачем, для обновления?  Это не лучшее решение, т.к. изменения происходят не так часто а вот глюк загрузки/выгрузки можно словить. Плюс если расплодится CUIX, то время загрузки/выгрузки возрастет.

Алексея Кулик выкладывал код на лиспе, там идея лучше
Каждый раз при загрузке плагина проверяешь дату создания CUIX, если изменилась, то выгружаешь CUIX, потом загружаешь.

Сверять собственно несчем, в основной CUIX к сожалению дату подгрузки частичных CUIX AutoCAD не записывает.
Алексей сверял даты локальной копии CUIX с сетевой. Выгружал, заменял, загружал вновь.

Для меня не очень подошло(т.к. у ноутов сети нет), и я стал сохранять дату загруженного CUIX в реестре. Как вариант можешь разместить в файле. и сверять с ней.

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 166
    • Мои плагины к Автокаду
Re: Подключить ленту из cuix
« Ответ #13 : 31-03-2021, 16:06:03 »
Это не лучшее решение
Однозначно. Потому и запилил такой вот велосипед.
Алексея Кулик выкладывал код на лиспе, там идея лучше
Каждый раз при загрузке плагина проверяешь дату создания CUIX, если изменилась, то выгружаешь CUIX, потом загружаешь.
Ужо. См. код
Сверять собственно несчем
Есть с чем. Автокад делает копию cuix из папки плагина в папку support. При обновлении плагина будет очевидное несоответствие. В коде выше уже реализовано (с оговоркой, что проверяется дата изменения главного cuix)

Оффлайн avcАвтор темы

  • ADN Club
  • *****
  • Сообщений: 822
  • Карма: 166
    • Мои плагины к Автокаду
Re: Подключить ленту из cuix
« Ответ #14 : 31-03-2021, 16:10:07 »
Так чего же его проверять в Initialize(), если можно проверить когда ComponentManager.Ribbon != null
Серьезное усложнение. И пользователю точно не понравится перезагрузка всего интерфейса, когда он уже работать начал. В Initialize - самый подходящий момент.