ChanServ changed the topic of #libreoffice-ru to: Канал поддержки русскоязычных пользователей LibreOffice | Wiki TDF http://tdf.io/wikiru | On-line документация http://tdf.io/helpru | Логи канала: http://goo.gl/gzwdwU
_whitelogger_ has joined #libreoffice-ru
Sveta has left #libreoffice-ru ["до свидания"]
JohnDoe_71Rus has joined #libreoffice-ru
tagezi_ has joined #libreoffice-ru
tagezi has quit [Ping timeout: 268 seconds]
_whitelogger has joined #libreoffice-ru
tagezi_ has quit [Quit: No Ping reply in 180 seconds.]
tagezi has joined #libreoffice-ru
kompi has joined #libreoffice-ru
<kompi> утра
<kompi> mikekaganski: то, что я вчера успел почитать про выделение в Либре и макросы мне совершенно не понравилось=(
<mikekaganski> :)
<mikekaganski> сделаем
<kompi> я не сомневаюсь
<kompi> mikekaganski: а еще мне приснилось, что либра начинает падать, после изменения всех формул в документе, потому что начинает жрать память засовывая все объекты в ОЗУ и не очищая ОЗУ после завершения операции=(
<mikekaganski> :))
<mikekaganski> Ну что, сделаем выделение?
<mikekaganski> для начала давай определимся с принципом. Возможны два варианта: 1. если что-то выделено в документе, работа идёт в выделенном, иначе везде; 2. Если есть выделение, то можно нажать галочку в диалоге
<kompi> 2 вариант, в первом может быть что-то выделено случайно или забыл юзер или мышой случайно двинул или еще что
<mikekaganski> Ок. Значит, нужно работать с диалогом.
<kompi> а может сделать две кнопки? "Форматировать все" и "Форматировать в выделенном диапазоне"?
<mikekaganski> Без разницы, оба варианта нормальные
<mikekaganski> выбирай, и приступим
<kompi> мне кажется вариант с двумя кнопками проще, просто откопировать процедуру, переименовать и добавить собственно ловлю выделения
<kompi> давай две кнопки
<mikekaganski> Если ты выбираешь, что проще, ты ошибаешься - одинаково. И мы не будем ничего копировать
<mikekaganski> но мне вариант с двумя кнопками тоже нравится больше
<mikekaganski> давай на нём и остановимся.
<kompi> ок
<mikekaganski> И теперь то, что я давно хотел, но теперь появился повод: для того, чтобы сделать хорошо с двумя кнопками, мы избавимся от глобальной переменной oDialog1, и изменим Formatting
<kompi> напомни мне про Option....чего-то там, чтобы переменные явно задавать всегда
<mikekaganski> Option Explicit
<kompi> хорошо (вот он рефакторинг)
<mikekaganski> в самом начале
<kompi> в каждой процедуре?
<kompi> или всего листинга?
<mikekaganski> нет, в самом начале файла
<mikekaganski> да
<kompi> доне
<mikekaganski> прогони программу; для каждой ошибки проверь, что в нужном месте есть Dim
<kompi> (про "давно хотел" мне понравилось)
<mikekaganski> Ну, ты же не думаешь, что я с чистого листа с тобой работаю: я всё это уже прогнал :)
<kompi> Doc=ThisComponent - это объект или строка?
<mikekaganski> Это объект
<mikekaganski> Dim oDoc As Object (я бы сделал oDoc вместо Doc)
<mikekaganski> но это вкусовщина
<kompi> Nobj=Doc.DrawPage.Count-1
<mikekaganski> dim nObj As Long
<kompi> mikekaganski: i для цикла как определять?
<mikekaganski> Перед циклом Dim i As Long
<kompi> доне
<mikekaganski> прекрасно
<kompi> олл доне
<mikekaganski> Теперь давай уберём oDialog1
<mikekaganski> Он у тебя устанавливается в DialogFormattingShow
<kompi> из начала листинга?
<mikekaganski> и нужен для того, чтобы Formatting знал, откуда брать элементы диалога и их значение
<kompi> угу
<kompi> чем он плох?
<mikekaganski> Но на самом деле это не нужно. Formatting вызывается, когда пользователь нажал на кнопку диалога; в этом событии есть возможность узнать, что за диалог активен
<mikekaganski> Любая глобальная переменная - плохо. Нужно стараться без них обходиться. Возможны варианты ошибок пользователя
<mikekaganski> и тогда глобальные переменные могут перетереться, или конфликтовать
<mikekaganski> использовать их нужно только если нет возможности обойтись без них
<mikekaganski> так вот
<mikekaganski> твой Formatting озаглавлен просто: Sub Formatting .... End Sub
<mikekaganski> Без каких-либо аргументов, передаваемых в него
<kompi> да
<mikekaganski> Он у тебя назначен кнопке форматирования в качестве обработчика нажатия
<kompi> да
<mikekaganski> так вот, Либра при нажатии передаёт туда специальный объект-событие, а ты его просто игнорируешь
<kompi> ЛИбра мне ничего не говорил
<mikekaganski> в этом объекте есть полезная информация, в частности - источник - объект-кнопка
<mikekaganski> ну и не долен говорить, он уважает твоё решение
<mikekaganski> "Ну что же, не нужен kompi объект - не буду настаивать" :))
<kompi> ок
<mikekaganski> Сейчас мы разделим обработку события (нажатия на кнопку) и работу по форматированию
<kompi> я знаю чего не хватает IDE Basic в ЛИбре: возможности сворачивать процедуры и функции под плюсик
<mikekaganski> для начала создадим маленькую процедуру: Sub OnFormattingClick(ByRef aMouseEvent)
<mikekaganski> Вот этот aMouseEvent и получит от ЛО данные о событии
<mikekaganski> В нём есть свойство Source - объект-кнопка
<mikekaganski> а у объекта-кнопки есть свойство Context - это диалог (тот самый объект, который пока что ты хранишь в глобальной oDialog1)
<mikekaganski> Поэтому достать этот объект в этой процедуре можно так: aMouseEvent.Source.Context
<kompi> вот она вся прелесть ООП
<mikekaganski> Теперь нужно передать его в твой Formatting
<mikekaganski> Для этого поправим Formatting так: Sub Formatting(ByRef oDialog)
<kompi> доне
<mikekaganski> Теперь внутри Formatting заменим все oDialog1 на oDialog (не нравится мне эта единица :))
<kompi> доне
<mikekaganski> Функция OnFormattingClick должна пока что выполнять всего одно действие: вызывать Formatting, передавая туда этот диалог
<mikekaganski> Вот так: Formatting(aMouseEvent.Source.Context)
<mikekaganski> Это единственная команда в OnFormattingClick
<kompi> не понял
<mikekaganski> Sub OnFormattingClick(ByRef aMouseEvent)
<mikekaganski> Formatting(aMouseEvent.Source.Context)
<mikekaganski> End Sub
<kompi> ок
<mikekaganski> теперь уберём из начала файла объявление глобальной oDialog1, а из DialogFormattingShow - её присвоение
<kompi> вообще?
<mikekaganski> да
<kompi> ок
<mikekaganski> и для кнопки диалога назначим обработчик нажатия OnFormattingClick вместо Formatting
<mikekaganski> это был подготовительный этап - мы сделали удобнее последующую работу с двумя кнопками
<mikekaganski> проверь, что работает
<kompi> проверить мона?
<kompi> гг
<kompi> не работает
<kompi> мы там список заполняем
<kompi> а теперь непонятно чей список
<mikekaganski> а, да, я слишком поторопился с "убери всё из DialogFormattingShow "
<kompi> и сам диалог показываем
<mikekaganski> Dim oDialog As Object
<mikekaganski> oDialog = LoadDialog("FAF", "FaF")
<kompi> в процедуре?
<mikekaganski> то есть это, конечно, там должно быть
<mikekaganski> да
<mikekaganski> просто оно теперь локальное, не глобальное
<kompi> угу
<kompi> единички убираем и долно работать?
<mikekaganski> и ведь ты ещё переспросил меня: "вообще?"
<mikekaganski> да
<kompi> робит, ок
<mikekaganski> ок, ехаем дале
<mikekaganski> добавь ещё кнопку для "обработать выделенное"
<kompi> уже
<mikekaganski> Там, где ты создал OnFormattingClick, скопируй эту маленькую функцию рядом, и назови её Sub OnSelectionFormattingClick(ByRef aMouseEvent)
<mikekaganski> пока что они делают одно и то же
<mikekaganski> Назначь эту новую функцию новой кнопке
<kompi> доне
<mikekaganski> ок. Теперь самое главное - работа с выделением
<kompi> угу
<mikekaganski> Для того, чтобы сделать твою главную функцию - Formatting - универсальной, мы должны сделать так, чтобы она могла работать в обоих случаях, просто для разных объектов
<kompi> ты уверен, что это лучше, чем две процедуры рядом?
<mikekaganski> Этого можно дбиться, если мы в неё передадим кким-то образом нечто, что сможет сказать, попадает этот объект в обрабатываемый диапазон или нет
<mikekaganski> однозначно
<kompi> погоди
<mikekaganski> имея две дублирующиеся функции, ты гарантированно нарываешься на баги, когда потом в одной поправил, во второй забыл
<kompi> хм
<kompi> ну ок, звучит разумно...
<kompi> ладно, го далее
<mikekaganski> например, в качестве хотелки у тебя есть "обрабатывать больше свойств функций"
<mikekaganski> так тебе придётся это делать в двух местах
<mikekaganski> го
<mikekaganski> предлагаю передавать в Formatting объект-выделение, который может быть пустым, и ввести новую функцию, которая сможет сказать нам, входит ли любой данный объект в это выделение
<mikekaganski> Это один из возможных вариантов, есть другие, просто этот проще вписывается в твою уже имеющуюся структуру
<mikekaganski> Итак, сейчас мы немного изменим Formatting ещё раз: Sub Formatting(ByRef oDialog, ByRef oSel)
<mikekaganski> этот oSel и будет объектом-выделением
<kompi> тыц тыц тыц...
<mikekaganski> Мы придумаем новую функцию IsInSelection - позже. А пока изменим условие, которое говорит нам, обрабатывать очередной объект в цикле или нет
<mikekaganski> If (Obj.supportsService("com.sun.star.text.TextEmbeddedObject")) then
<mikekaganski> Это у тебя сейчас так
<mikekaganski> ну, или почти так
<kompi> угу
<mikekaganski> То есть каждый объект у тебя проверяется (процедура принимает решение, возиться с ним дельше или нет)
<mikekaganski> так мы добавим ещё условие
<mikekaganski> If (IsInSelection(Obj, oSel) And Obj.supportsService("com.sun.star.text.TextEmbeddedObject")) then
<mikekaganski> То есть обрабатывать дальше будем только если этот объект нужного типа, и при этом входит в выделение
<mikekaganski> как я уже сказал, IsInSelection - это пока воображаемая функция, которую мы сделаем реальной - начнём прямо сейчас
<kompi> погоди
<mikekaganski> годю
<kompi> я чуть не уловил
<kompi> мне изменить существуюшее условие или добавить новое?
<mikekaganski> изменить
<mikekaganski> я добавил условие в существующую строчку - посмотри на неё внимательно
<mikekaganski> сравни до и после
<kompi> я вижу
<mikekaganski> далее?
<kompi> ты просто сформулировал "добавим", это меня смутило
<kompi> да, го
<mikekaganski> Function IsInSelection(ByRef oObj, ByRef oSel) ... End Function
<mikekaganski> Эта функция принимает объект (например, формулу) и объект-выделение, и должна нам сказать, входит первый во второй или нет (т.е., работать дальше или нет)
<mikekaganski> я имею ввиду, работать дальше с этим объектом, или игнорировать его и перейти к следующемы
<mikekaganski> пока что заставим эту функцию всегда говорить "да, работать" - это будет временная заглушка
<kompi> хм
<mikekaganski> Единственным действием пока что пропишем ей IsInSelection = true
<mikekaganski> Получится вот что:
<mikekaganski> Function IsInSelection(ByRef oObj, ByRef oSel)
<mikekaganski> IsInSelection = екгу
<mikekaganski> End Function
<mikekaganski> true
<mikekaganski> сорри
<kompi> переменная IsInSelection это?
<mikekaganski> Это имя функции
<mikekaganski> Когда внутри функции мы присваиваем что-то самой функции - мы говорим, какой будет результат у функции
<kompi> то есть ее не надо объявлять, как переменную? оно внутри себя ссылается на сеяб же?
<mikekaganski> Да
<kompi> ясно
<mikekaganski> Чего мы пока что добились? Во-первых, что ничего не работает
<kompi> подсветки имен процедур и фнкций тоже не хватает
<mikekaganski> во-вторых, что теперь нам нужно что-то передавать в Formatting, и это что-то будет разным в случае одной и другой кнопок
<mikekaganski> И теперь мы поработаем с тем, как же получить выделение документа
<mikekaganski> У документа есть свойство - CurrentSelection
<kompi> ага!
<kompi> я ж говорил вчера, что пепяка есть
<mikekaganski> Этот объект может содержать несколько выделенных диапазонов текста (например, когда ты делаешь выделение с Ctrl)
<kompi> а если не текста?
<mikekaganski> а может содержать один графический объект (если ты щёлкнул по формуле, и она сейчас выделена с помощью ручек в документе)
<kompi> погоди
<kompi> почему ОДИН объект
<mikekaganski> и даже несколько графических дкументов, выделенных через Ctrl
<mikekaganski> Но формулы не выделяются по нескольку, так что нам пока последний вариант не нужен
<mikekaganski> Если выделения нет, объект CurrentSelection всё равно есть, и он показывает единственный выделенный диапазон текста - который начинается на курсоре, и заканчивается тоже на курсоре
<mikekaganski> то есть имеет нулевую длину
<kompi> подожди
<kompi> ты сейчас рассматриваешь только документ Writer
<mikekaganski> жду
<kompi> а Draw?
<kompi> в Draw формулы можно выделить рамочкой и они прекрасно выделяются
<mikekaganski> А почему ты не работаешь с Calc?
<mikekaganski> там тоже можно вставить формулу
<kompi> давай тогда определимся, что ни в каких иных модулях это работать не будет, так получается?
<mikekaganski> А у тебя оно работало в Draw?
<kompi> я вот сейчас сунулся проверить, а оно же у нас испорчено пока
<kompi> а у тебя не работало?
<mikekaganski> нет
<kompi> хм
<mikekaganski> но ты можешь пока проверить
<mikekaganski> в твоих функциях
<mikekaganski> OnFormattingClick
<kompi> текстэмбеддинг объект
<mikekaganski> исправь Formatting(aMouseEvent.Source.Context) на Formatting(aMouseEvent.Source.Context, Nothing)
<kompi> то есть это объект вставленный в текст, а это Вритер, так получается?
<mikekaganski> там раньше проблема вылезет - в Draw нет DrawPage :)
<mikekaganski> но раз ты заговорил про другие модули - это гут
<mikekaganski> давай тогда пересмотрим наш подход в пользу более универсального
<mikekaganski> это, правда, потребует бОльших модификаций (в т.ч. в Formatting), но зато позволит расшириться впоследствии на другие модули
<mikekaganski> и пока мы не сделали много, сейчас самое время для такого решения
<kompi> да, давай универсалить
<kompi> идея была, что на плакатах также могут быть формулы и их также нужно будет подгонять под формат листа или типа того
<mikekaganski> прекрасно. Тогда давай договоримся так: в Formatting будем просто передавать уже подготовленный список объектов. И этим мы займёмся в другом месте, а Formatting не будет уже перебирать объекты, а будет работать уже с отобранными
<kompi> нет проблем
<mikekaganski> тогда её объявление станет таким: Sub Formatting(ByRef oDialog,ByRef vFormulaObjects)
<kompi> ага
<mikekaganski> второй параметр - это массив (вектор) объектов под обработку. Если мы захотим обработать весь документ - мы должны будем подготовить массив всех объектов; если только выделение - значит, только выделение
<kompi> значит, только объекты, которые попали в выделение
<kompi> ок
<mikekaganski> На долю Formatting останется только проверить, что это формула, и применить форматирование
<kompi> логично =)
<mikekaganski> Так, чтобы мне работать с твоим кодом, отправь твою Formatting в pastebin
<mikekaganski> ок. Смотри: раньше нам нужен был Doc для того, чтобы из него выцепить объекты. А теперь нам объекты уже дают готовые, на блюдечке
<mikekaganski> так что строки 5, 6, 8 и 9 не нужны.
<mikekaganski> в цикле (строки 27-47) мы будем теперь перебирать объекты из массива
<mikekaganski> так что строчка 27 преобразуется, чтобы i менялась внутри границ массива
<mikekaganski> For i=LBound(vObjects) to UBound(vObjects)
<mikekaganski> то есть i меняется от нижней до верхней границ массива
<mikekaganski> строки 28-29 тоже не нужны. Нужные действия должны бить уже сделаны там, где будет формироваться массив
<mikekaganski> (и строка 46)
<mikekaganski> и тогда строка 30 превратится вот во что: Obj1=vObjects(i).getEmbeddedObject
<kompi> 'v
<kompi> эм
<mikekaganski> жду
<mikekaganski> ?
<kompi> я пытаюсь строки соотнести
<kompi> которые снести
<mikekaganski> ну, я ориентируюсь по листингу в пейстбине
<kompi> вроде все
<kompi> mikekaganski: на сегодня все, я так понимаю? тебе нужно время на опыты? =)
<mikekaganski> о, ты уже написал, я не увидел, сорри
<mikekaganski> так, теперь нам нужно будет сделать разные процедуры для разных модулей
<mikekaganski> и начнём с Writer, чтобы восстановить для начала уже имеющийся функционал
<mikekaganski> Займёмся тем, как мы хотим, чтобы выглядела функция-обработчик событий
<mikekaganski> OnFormattingClick
<mikekaganski> Она должна сама взять документ, получить его объекты (все!), и отправить в Formatting
<mikekaganski> OnFormattingClick
<mikekaganski> OnSelectionFormattingClick
<mikekaganski> эта должна сделать почти то же самое: только получить не все объекты, а только выделенные
<mikekaganski> её оставим на потом
<mikekaganski> пока займёмся OnFormattingClick
<mikekaganski> ок?
<kompi> ессно
<mikekaganski> тогда давай переделаем её вот так: https://pastebin.ca/3956139
<kompi> ага
<mikekaganski> Здесь мы сначала объявляем объект oDialog и считываем его из объекта-события, переменную-документ - из ThisComponent, это всё уже было
<kompi> да
<mikekaganski> самое главное здесь - вызов Formatting(oDialog, GetObjectsFromDoc(oDoc, Nothing))
<mikekaganski> мы тут используем пока что ненаписанную GetObjectsFromDoc
<kompi> db;e
<kompi> вижу
<mikekaganski> Она должна взять две вещи: документ и выделение, и вернуть список объектов
<mikekaganski> сейчас её и начнём
<mikekaganski> Она тоже будет делать всё не сама, а с помощью других функций
<mikekaganski> потому что документы бывают разные: Writer, Draw, Calc
<kompi> я вот думаю, Импресс надо ли?
<mikekaganski> Так что задачей GetObjectsFromDoc будет просто определить, что это за документ, и в зависимости от этого вызвать специализированную функцию
<mikekaganski> а Draw и Impress одинаковы
<kompi> месторасположение процедур относительно друг друга в листинге имеет значение?
<mikekaganski> нет
<kompi> ок
<mikekaganski> Итак: Function GetObjectsFromDoc(ByRef oDoc, ByRef oSel) ... End Function
<mikekaganski> Начнём с самого минимума: пусть она для начала возвращает пустой массив (пока что она ещё не умеет работать НИ С КАКИМ документом)
<mikekaganski> Для этоо вначале создадим переменную - пустой массив, и вернём её, вот так:
<mikekaganski> Dim vObjects() As Object
<mikekaganski> GetObjectsFromDoc = vObjects
<kompi> ок
<mikekaganski> Создали пустой массив, вернули его. Всё. После этого всё должно работать, но ничего не форматировать (по крайней мере, если я ничего не забыл тебе сказать)
<mikekaganski> давай проверим на этом этапе
<kompi> если имя переменной при объявлении имеет скобки, это массив?
<mikekaganski> да
<kompi> For i=LBound(vObjects) to UBound(vObjects) - переменаая не определена
<mikekaganski> kompi: лучше скриншот (непонятно, где это)
<kompi> в Форматтинге
<mikekaganski> Ну, я там использовал vObjects вместо vFormulaObjects - и тебе советую поменять vFormulaObjects на vObjects в аргументах
<mikekaganski> потому что мы только здесь проверяем, формула это или нет
<mikekaganski> кстати, у тебя там больше Obj не используется, так что его объявление можно убить
<kompi> все делает без ошибок но ничего не делает=)
<kompi> давай прервемся, или до глубокого вечера или до завтра
<mikekaganski> прекрасно! потом что объектов не передаёт
<mikekaganski> ок
<kompi> я может почитаю Питоньяка на ночь (правда смысл его читать без практики?)
<kompi> бай
<mikekaganski> :)
kompi has quit [Quit: Page closed]
kompi has joined #libreoffice-ru
JohnDoe_71Rus has quit [Quit: KVIrc 4.9.3 Aria http://www.kvirc.net/]
kompi has quit [Quit: Page closed]
kompi has joined #libreoffice-ru
<kompi> mikekaganski: нааомни мне рассказать тебе про длиннющий путь до установленного нашего расширения в либре
<kompi> Потом напомни
<mikekaganski> ok
kompi has quit [Quit: Bye]