Недоработки механизма локализации (???)

Автор Тема: Недоработки механизма локализации (???)  (Прочитано 37655 раз)

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

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Недоработка механизма локализации
« Ответ #15 : 26-12-2013, 16:41:56 »
Повторюсь. Логика работы AutoCAD во все времена: "язык плагина" == "язык AutoCAD". Соответственно и справка должна быть на том языке, на котором AutoCAD.
Дело в том, что в .NET нет такого понятия как "язык плагина" (если отделять локализацию от кода, что собственно я обычно и делаю): один и тот же плагин может быть установлен как в русском, так и в английском AutoCAD. А поскольку локализованные ресурсы выносятся в отдельный файл ресурсов (dll), то нужная локализация автоматически находится и подставляется самой .NET, в виду чего один и тот же плагин в английском автокаде отображает английский интерфейс, а в русском - русский. Но сам по себе плагин (dll файл с кодом команд) один. А вот справка... Она же читается не автоматом из dll, а из файла chm, который нужно как-то указать уникально для каждой локализации свой...

Цитата: Александр Ривилис
В данном случае чтобы реализовать то, что нужно Андрею, следует в методе IExtensionApplication.Initialize проверить локализацию и вызвать acedSetFunHelp с параметрами, зависящими от локализации. В этом случае нажатие F1 в AutoCAD для данной команды (команд) должно приводит к вызову соответствующей справки.
Фактически acedSetFunHelp занимается тем, что заносит во внутреннюю таблицу AutoCAD тройку строк имя команды-имя файла помощи-имя раздела помощи. При нажатии F1 AutoCAD проверяет эту таблицу и вызывает нужный раздел нужной справки.
Я не увидел этот ответ, только сейчас заметил. Да, нужно будет попробовать, хотя у меня безуспешные попытки вроде уже были.

Например, в IExtensionApplication.Initialize ты копируешь в нужное место соответствующий языку локализации файл.
Хм... Как вариант, конечно же подходит, если файлы справки хранятся в каталоге, доступном юзеру для редактирования (например, в %AppData%).
« Последнее редактирование: 26-12-2013, 17:24:52 от Андрей Бушман »

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Недоработка механизма локализации
« Ответ #16 : 26-12-2013, 17:37:49 »
Кстати, вот же ещё неприятный момент:
Цитировать
Чтобы справка открывалась не только под отладкой, нужно в каталоги поиска САПР (Support File Search Path) добавить путь к каталогу плагина (в абсолютной или относительной форме).
Если это выполнять для каждого плагина, то сами понимаете, во что превратится Support File Search Path... Было бы неплохо, если бы AutoCAD искал справку плагина относительно каталога его сборки.

Пока что попробую разрулить этот момент через acedSetFunHelp.

Ну, давайте, закидывайте меня бананами....

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Недоработка механизма локализации
« Ответ #17 : 26-12-2013, 17:42:53 »
Ну, давайте, закидывайте меня бананами...
Бананами не буду. Если использовать технологию с acedSetFunHelp то просто пропишешь полные пути и всё. А вот с учетом того, что и для CommandAttribute используется тот же acedSetFunHelp и после этого AutoCAD уже понятия не имеет о том, что этот вызов был из твоего модуля - тут вряд ли возможно что-то сделать.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Возвращаясь к нашим бананам...

- AutoCAD 2014 SP1 x64 Enu
- AutoCAD 2009 SP3 x64 Enu

Читаю это:
Цитата: acedSetFunHelp
Defines a Help call that should be made if a transparent Help request is made during a command line prompt for the function named pszFunctionName.

This function registers Help for functions that are called from the AutoCAD command line so that the appropriate Help file and topic are called when help is requested at a user prompt. acedSetFunHelp() may be used for ObjectARX commands, as well as ObjectARX and AutoLISP commands that start with C:.
По началу, меня несколько насторожило  отсутствие упоминания команд, написанных на .NET... Однако практика показала, что опасения были напрасны. В качестве "подопытной кошки" выступал chm-файл, прикреплённый во вложении.

Код - C# [Выбрать]
  1. // Commands.cs
  2. // © Andrey Bushman, 2013
  3. // Перехват и обрабока вызова раздела справочной системы для команд AutoCAD
  4.  
  5. // Microsoft
  6. using System;
  7. using System.Resources;
  8. using System.IO;
  9. using System.Runtime.InteropServices;
  10.  
  11. // Autodesk
  12. using cad = Autodesk.AutoCAD.ApplicationServices.Application;
  13. using Ed = Autodesk.AutoCAD.EditorInput;
  14. using Rtm = Autodesk.AutoCAD.Runtime;
  15.  
  16. [assembly: Rtm.ExtensionApplication(typeof(Bushman.CAD.Tests.Commands))]
  17. [assembly: Rtm.CommandClass(typeof(Bushman.CAD.Tests.Commands))]
  18.  
  19. namespace Bushman.CAD.Tests {
  20.         public class Commands : Rtm.IExtensionApplication {
  21.  
  22. #if acad_newer_than_2012
  23.                 const String acedSetFunHelpOwner = "accore.dll";
  24. #else
  25.                 const String acedSetFunHelpOwner = "acad.exe";
  26. #endif
  27.                 // © Adam Nagy, 2012
  28.                 // Source: http://adndevblog.typepad.com/autocad/2012/05/change-help-file-and-topic-associated-to-a-given-command.html
  29.                 // In case of AutoCAD 2013 and above
  30.                 // replace "acad.exe" with "accore.dll"
  31.                 [DllImport(acedSetFunHelpOwner, CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl,
  32.                         EntryPoint = "acedSetFunHelp")]
  33.                 private static extern int acedSetFunHelp(String functionName, String helpFile, String helpTopic,
  34.                         Int32 cmd);
  35.  
  36.                 [Rtm.CommandMethod("bushman", "test", Rtm.CommandFlags.Modal)]
  37.                 public void Test() {
  38.                         Ed.Editor ed = cad.DocumentManager.MdiActiveDocument.Editor;
  39.                         ed.WriteMessage("\nHello, World!\n");
  40.  
  41.                         // Чтобы можно было проверить вызов справки для командной строки в AutoCAD 2009
  42.                         ed.GetInteger("Type some integer value");
  43.                        
  44.                 }
  45.  
  46.                 public void Initialize() {
  47.                         Ed.Editor ed = cad.DocumentManager.MdiActiveDocument.Editor;
  48.                         ed.WriteMessage("\nThe {0} loaded...\n", Path.GetFileName(this.GetType().Assembly.Location));
  49.  
  50.                         // В качестве теста взял один из своих старых файлов справки (DrawingQuickCopyHelp.chm)
  51.                         // и закинул его на "рабочий стол" - тренируюсь, так сказать, "на кошках"...
  52.  
  53.                         acedSetFunHelp("C:LINE", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
  54.         "DrawingQuickCopyHelp.chm"), "dwgquickcopy", 0);
  55.                         acedSetFunHelp("C:CIRCLE", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
  56.                                 "DrawingQuickCopyHelp.chm"), "settings", 0);
  57.  
  58.                         // Регистрирую свою ".net" команду
  59.                         acedSetFunHelp("test", Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
  60.                                 "DrawingQuickCopyHelp.chm"), "contacts", 0);
  61.  
  62.                         ed.WriteMessage("\nThe help info registered...\n");
  63.                 }
  64.  
  65.                 public void Terminate() {
  66.                         // is empty
  67.                 }
  68.         }
  69. }

Маленькое отступление... А.Н. Ривилис здесь дал комментарий:
Цитата: Alexander Rivilis
Hi, Adam!
What about that LINE is not Autolisp-definded command and so you have to use not "C:LINE", but "LINE" in your's code?

Я проверял для команд LINE и CIRCLE два варианта - с префиксом "C:" и без него: в обоих случаях результат получается один и тот же. Теперь о результатах, полученных в AutoCAD 2014 SP1:

1. В случае с Line и Circle переопределение справки работает для "риббонов" и "туллбаров", но не для командной строки AutoCAD.
2. В случае с Test (т. е. для моей .NET команды) переопределение справки работает для "риббонов" и командной строки AutoCAD, но не для "туллбаров".

А вот в AutoCAD 2009 SP3, для определённых мною .net команд, это работает во всех трёх ситуациях (риббон\туллбар\командная строка). ;D Хотя для команд LINE и CIRCLE в AutoCAD 2009 SP3 поведение наблюдается такое же, как и в случае с AutoCAD 2014 SP1, но для меня важно, чтобы корректно работало для созданных мною команд.  ;)

P.S. Я пробовал регистрировать и полное имя команды, с указанием её пространства имён: "bushman.test" (думал: мало ли, может это поможет), но в этом случае открывается справка AutoCAD, а не моя. Значит регистрацию всегда нужно проводить без участия namespace команды.
« Последнее редактирование: 27-12-2013, 12:41:00 от Андрей Бушман »

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Кончено в зависимости от ситуации, но "топорный" метод проверки локализации и переноса в случае необходимости .chm может быть даже более "интересным" - например в случае 1 сборка, 1 .chm и кучка команд.

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Кончено в зависимости от ситуации, но "топорный" метод проверки локализации и переноса в случае необходимости .chm может быть даже более "интересным" - например в случае 1 сборка, 1 .chm и кучка команд.
я не понял этой фразы.

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Александр Ривилис, в этой теме предлагал 2 варианта решения, 1 "правильный" - использовать импорт acedSetFunHelp и установить в ручную привязки путей помощи, и 2-ой "топорный" - во время загрузки библиотеки - IExtensionApplication.Initialize - проверить соответствие локализации файлу помощи и если необходимо - заменить. Пути к помощи при этом "жестко" прописанны в соответствующем аттрибуте CommandMethod. Минус что справку придеться хранить в доступной для записи области и "работать с файлами" при загрузке, но зато (если 1 справка на все команды), не париться с установкой на каждую команду (то есть исключаються варианты типа добавил команду в сборку, в справку, но забыл ее правильно инициализировать).

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
но зато (если 1 справка на все команды), не париться с установкой на каждую команду (то есть исключаються варианты типа добавил команду в сборку, в справку, но забыл ее правильно инициализировать).
А как AutoCAD будет знать, что ему нужно обработать еще одну команду? Т.е. в любом случае для каждой команды нужен будет  свой CommandAttribute с именем файла справки и раздела справки. Хотя идею с IExtensionApplication.Initialize можно развить на "правильном" пути - при помощи Reflection получить все команды в сборке и им назначить через acedSetFunHelp справку. Вот тогда действительно можно будет "не парится" с назначением помощи каждой из команд.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Хотя идею с IExtensionApplication.Initialize можно развить на "правильном" пути - при помощи Reflection получить все команды в сборке и им назначить через acedSetFunHelp справку. Вот тогда действительно можно будет "не парится" с назначением помощи каждой из команд.
Именно это я сейчас и делаю в качестве примера... :)

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
А вот в AutoCAD 2009 SP3, для определённых мною .net команд, это работает во всех трёх ситуациях (риббон\туллбар\командная строка). ;D
Странно. В той же статье Адам Наги пишет, что для тултипов работать не должно - нужно править CUIx.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Странно. В той же статье Адам Наги пишет, что для тултипов работать не должно - нужно править CUIx.
Я в CUI создал новую кнопку, палитру кнопок, палитру риббона, вкладку риббона. Назначил кнопке свою команду test. Добавил в текущий workspace свою вкладку риббона и обычную палитру с кнопкой. Вот на этом и тестировал.

В AutoCAD 2009 нет CUIx меню, они появились только начиная с 2010.

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Цитировать
Т.е. в любом случае для каждой команды нужен будет  свой CommandAttribute с именем файла справки и раздела справки
Да нужно, но она 1 - не надо будет "обрабатывать" каждую команду. То есть делаешь аттрибут как будто справка на 1 языке, и забываешь.
А насчет - через Reflection назначить сразу всей сборке - тогда надо придумывать (и соблюдать) алгоритм взаимосвязи имени (или других аттрибутов) функции от названия файла справки и названия топика - что по моему лишнее.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Тут то как раз всё просто: "имя команды" == "имя раздела справки", "имя файла справки" == "имя сборки".
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Первые наброски готовы... Я написал пример плагина в котором:

1. При загрузке его в AutoCAD, в консоль AutoCAD выводится информация о командах, определённых в составе этого плагина: глобальные и локализованные имена команд, с указанием их групп (если они заданы). Так же выводится локализованное краткое примечание по каждой команде (что она делает). Вся обозначенная выше информация вычисляется динамически (через Reflection), не зависимо от того, сколько классов\методов определено в сборке.

2. Для каждой команды выполняется регистрация информации касательно пользовательской справки и раздела, относящихся к команде. При вызове справки для команды, открывается нужный локализованный вариант справки по этой команде.

3. По умолчанию в плагине используется локализация AutoCAD, но пользователь может указать иную. В этом случае при очередном вызове команд или попытке посмотреть их справку, вся информация будет предоставляться на указанной юзером локализации (перезагрузка AutoCAD не требуется). Если ресурсов под указанную локализацию нет, то используются те, что Default.

Можно использовать как заготовку для новых плагинов, чтобы каждый раз заново не реализовывать в плагине механизм, обозначенный выше. Сегодня уже не успеваю оформить презентабельно - если в воскресенье (у нас рабочий день) успею, то оформлю и опубликую. А так, всё работает пучком...

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Будет интересно посмотреть и покритиковать!  :)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение