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
tagezi_ has joined #libreoffice-ru
tagezi has quit [Ping timeout: 248 seconds]
tagezi_ is now known as tagezi
JohnDoe_71Rus has joined #libreoffice-ru
<mikekaganski> kompi: ну что, почувствовал, почему я изначально предлагал сделать возможным не менять шрифт? :)
<JohnDoe_71Rus> не на любой шрифт можно сменить. а то там не будет символов и все поедет к чертям
mikekaganski has quit [Read error: Connection reset by peer]
mikekaganski has joined #libreoffice-ru
tagezi has quit [Ping timeout: 240 seconds]
tagezi has joined #libreoffice-ru
kompi has joined #libreoffice-ru
<kompi> mikekaganski: да я и не спорю, возможность изменить только кегль - это хорошая идея
<mikekaganski> Ну вот, теперь ты можешь её реализовать
<kompi> бггг
<kompi> погоди
<mikekaganski> Сначала давай сделаем вывод всех системных шрифтов
<kompi> меня больше всего смущает зависон лирбы при установке расширения
<kompi> давай
<mikekaganski> Я тебе кидал ссылку на Питоньяка по этому поводу
<kompi> mikekaganski: а для трех разных ОС не надо будет городить огород со шрифтами?
<kompi> кинь еще раз, я на тедлефоне тогда смотрел
<mikekaganski> Listing 305. Check a document for a font.
<mikekaganski> Стр. 325
<mikekaganski> Там важно то, что можно получить список шрифтов у текущего окна
<mikekaganski> две строки:
<kompi> саму ссылку на книгу
<mikekaganski> oWindow = oDoc.getCurrentController().getFrame().getContainerWindow()
<mikekaganski> и
<mikekaganski> oFonts() = oWindow.getFontDescriptors()
<mikekaganski> Это начало, это не всё, конечно, но от этого мы оттолкнёмся
<mikekaganski> Нам нужно будет сделать процедуру заполнения списка шрифтов
<mikekaganski> Давай назовём её Sub FillFontsList
<mikekaganski> реакции нет
<kompi> я читаю листинг еще раз просто
<mikekaganski> ок, жду
<kompi> процедуру или функцию?
<mikekaganski> Ты хочешь, чтобы она возвращала какое-то значение?
<kompi> да
<mikekaganski> какое?
<kompi> имя шрифта
<kompi> эээ
<kompi> так погоди
<kompi> мы ищем список шрифтов, чтобы юзеру было из чего выбирать
<kompi> эта штука должна нам дать список
<kompi> так?
<mikekaganski> Можно сделать и так
<kompi> а можно как?
<mikekaganski> можно всё запрятать внутрь процедуры: ты её вызываешь, передаёшь в неё элемент-список, она его заполняет
<mikekaganski> ты не паришься с её возвращаемым значением
<kompi> она заполняет список и мы его потом подставляем в элемент диалога?
<mikekaganski> нет, элемент диалога ты передашь в процедуру, она всё заполнит
<mikekaganski> выглядеть будет так:
<kompi> ну давай попробуем
<mikekaganski> Sub FillFontsList(oListBox)
<mikekaganski> ... Утв Ыги
<mikekaganski> End Sub
<mikekaganski> ...
<mikekaganski> FillFontsList(oDialog.GetControl("ListBox1"))
<mikekaganski> давай
<mikekaganski> В начале функция будет почти как у Питоньяка
<kompi> я так не могу
<mikekaganski> как?
<kompi> мне нужно понимание, что я делаю
<mikekaganski> я и объясняю
<mikekaganski> по-русски
<mikekaganski> и мне приходится стирать то, что я написал, чтобы ответить на "я так не могу"
<mikekaganski> итак: функция должна получить объект окна, который знает обо всех шрифтах
<kompi> да
<mikekaganski> Питоньяк показывает, как это сделать: объявляет переменную "окно" (oWindow), и затем присваивает ей значение ThisComponent.getCurrentController().getFrame().getContainerWindow()
<mikekaganski> Мы делаем то же самое, здесь ничего менять не нужно
<mikekaganski> У окна есть функция getFontDescriptors, которая возвращает объект "перечень описаний шрифтов"
<kompi> угу, сделали
* kompi копипаст-"программист"
<mikekaganski> вначале это нормально
<mikekaganski> так вот, этот объект - это ещё не совсем тот список, который нам нужен.
<mikekaganski> чтобы заполнить листбокс, нам нужно либо в цикле добавлять в него по одной строке, либо единовременно отправить в него сразу большой список строк
<mikekaganski> давай начнём с первого
<mikekaganski> итак, как и у Питоньяка, давай получим тот объект - перечень шрифтов - в переменную oFonts
<mikekaganski> сделал?
<kompi> oFonts()=oWindow.getFontDescriptors()
<mikekaganski> да
<mikekaganski> теперь, поскольку это массив объектов-описателей шрифтов, мы можем в цикле получать у каждого объекта имя шрифта
<mikekaganski> Цикл показан у Питоньяка (индекс i последовательно меняется от наименьшего индекса массива до наибольшего)
<mikekaganski> но делать внутри цикла мы будем немного другое
<kompi> а что за иФ внутри? что он проверяет?
<kompi> ааа
<mikekaganski> Между For и Next у нас будет только одна строчка
<mikekaganski> Эта строчка будет, собссна, добавлять имя шрифта в листбокс
<mikekaganski> Добавление одиночной строки в листбокс делается методом oListBox.AddItem(string, n)
<mikekaganski> где string - это просто строчка, которая появится в списке, а n - это позиция (порядковый номер), где она появится
<mikekaganski> В качестве порядкового номера мы можем пока использовать просто тот самый i
<kompi> FillFontsList(oDialog.GetControl("ListTypeFonts"))=oListBox.AddItem(string, i)
<kompi> >_<
* kompi мартышка=(
<mikekaganski> а строка - имя шрифта, которое мы получим, как и у Питоньяка, с помощью oFonts(i).Name
<mikekaganski> ой
<mikekaganski> это было что?
<kompi> =(
<kompi> это был полет мысли, щас сотру
<mikekaganski> мы с тобой обсуждали то, что мы должны делать внутри цикла, между for и next
<kompi> угу
<kompi> это мы и делаем (ты делаешь, а я пытаюсь не заблудиться)
<mikekaganski> на данный момент у нас должно было получиться нечто такое:
<mikekaganski> For i = LBound(oFonts()) To UBound(oFonts())
<mikekaganski> oListBox.AddItem(oFonts(i).Name, i)
<mikekaganski> Next
<kompi> погоди
<kompi> строка в цикле ничего ничему не присваивает?
<mikekaganski> То есть для каждого значения i (которое последовательно принимает значения от наименьшего до наибольшего индекса списка шрифтов) мы добавляем имя этого шрифта в наш листбокс в соответствующую позицию
<mikekaganski> она добавляет
<mikekaganski> вопросы?
<kompi> я не понял строку в цикле
<mikekaganski> По-русски это будет примерно так:
<kompi> для меня это выглядит как просто перебор, который никуда дальше не идет, поскольку не сохраняется
<mikekaganski> "Листбокс! Добавь к себе в список имя шрифта i в позицию i"
<mikekaganski> oListBox.AddItem(oFonts(i).Name, i)
<kompi> листбокс это массив?
<mikekaganski> Листбокс - это элемент диалога
<mikekaganski> мы вначале договорились, что этот элемент мы передадим в процедуру, чтобы процедура его заполняля
<kompi> так погоди, давай тогда добьем целиком всю процедуру и тогда я буду осмысливать
<mikekaganski> и мы договорились, что процедура у нас будет выглядеть как Sub FillFontsList(oListBox) ... End Sub
<kompi> да
<kompi> она так и выглядит пока
<mikekaganski> прекрасно
<mikekaganski> В общем-то почти всё для начала. Сейчас ты увидешь много недоделок, но для начала достаточно. Осталось только вызвать эту процедуру в нужном месте
<mikekaganski> Когда же нам заполнять список?
<kompi> когда юзер нажал мышкой на выпадающий список в диалоге
<mikekaganski> это нужно делать после того, как окно создано, но до того, как пользователь его увидел
<kompi> э?
<mikekaganski> нет, не когда мышкой
<kompi> пачЕму?
<mikekaganski> Потому что это должно делаться один раз, а не каждый раз при нажатии. Или ты думаешь, что список будет каждый раз новый?
<kompi> хм
<mikekaganski> у тебя есть процедура, которая открывает диалог
<kompi> есть
<mikekaganski> DialogFormattingShow
<mikekaganski> в ней oDialog = LoadDialog("FAF", "FaF") собственно создаёт диалог, а oDialog.Execute() - показывает его пользователю
<kompi> угу
<kompi> между ними надо вставить вызов процедуры со списком?
<mikekaganski> между ними и нужно сделать
<mikekaganski> да
<kompi> как вызывается процедура?
<mikekaganski> пишется её имя, а потом в скобках - то, что ты в неё передаёшь
<mikekaganski> в данном случае процедура называется FillFontsList, а передать в неё ты должен листбокс
<kompi> FillFontsList(oListBox)?
<kompi> или листбокс из диалога?
<mikekaganski> именно из диалога
<mikekaganski> ты его уже использовал в другой процедуре
<mikekaganski> oDialog.GetControl("ListBox1")
<kompi> хм
<kompi> FillFontsList(oDialog1.GetControl("ListTypeFonts"))
<mikekaganski> Прекрасно
<kompi> я поменял имя выпадающему списку
<mikekaganski> теперь можешь попробовать
<mikekaganski> тормозам не пугайся - это нормально - пока
<mikekaganski> это будет недоделка номер раз
<kompi> где ему нужна переменная? глобальная?
<mikekaganski> Хм, да. У Питоньяка есть тот самый jDoc
<mikekaganski> а мы используем ThisComponent
<mikekaganski> oWindow = ThisComponent.getCurrentController().getFrame().getContainerWindow()
<kompi> это надо прописать? или это мысли вслух?
<mikekaganski> Это я исправил тебе строчку
<kompi> сработало
<mikekaganski> он же тебе показал, где ошибка; я сказал, что на что нужно заменить в ней, и отправил исправленную строку
<kompi> тормозов особо нет
<kompi> шрифт не по алфавиту в списке
<mikekaganski> при открытии окна не тормозит?
<kompi> нет
<mikekaganski> у тебя сколько шрифтов?
<kompi> ну если самое чутка и диск шуршит
<kompi> откуда я знаю?
<kompi> сколько в винде+либровские
<mikekaganski> ну, ладно. У меня их около 300
<mikekaganski> и тормозит секунд 5
<mikekaganski> тормозило
<mikekaganski> "не по алфавиту" - это недоделка номер два
<mikekaganski> есть ещё номер три
<mikekaganski> если сейчас не заметишь, посмотрим после того, как отсортируем
<mikekaganski> в старбейсике нет встроенной процедуры сортировки, к сожалению
<mikekaganski> о, молодец
<kompi> дублируются шрифты
<kompi> список километровый ппц
<mikekaganski> так что ты увидел все проблемы уже (ну, кроме тормозов)
<mikekaganski> Исправление второй проблемы автоматом уберёт и тормоза, так что не судьба тебе это почувствовать
<kompi> :D
<mikekaganski> начнём с сортировки
<kompi> пузырьком?=(
<mikekaganski> алгоритмы сортировки - это отдельная песня
<mikekaganski> и мы воспользуемся алгоритмом отсюда: https://rosettacode.org/wiki/Sorting_algorithms/Quicksort#BASIC
<mikekaganski> но модифицированным мной для оптимальной производительности
* kompi в авторы расширения пропишет Майка
<mikekaganski> kompi: https://pastebin.ca/3955773
<kompi> куда это девать?
<mikekaganski> Здесь я не описываю весь алгоритм по шагам - просто возьми его себе. Это нормально, поскольку это алгоритм общего назначения, фактически, библиотечная функция, которую ты используешь как чёрный ящик
<mikekaganski> это процедура, помести её куда-нибудь перед своими процедурами
<kompi> и перед открытием диалога?
<mikekaganski> и использовать её мы будем так: quicksort(массив, индексМин, индексМакс)
<mikekaganski> нет ещё
<mikekaganski> эта процедура сортирует массив (строк или чисел). А у нас нет никакого массива строк
<kompi> а?
<kompi> это я понял
<mikekaganski> Мы не создавали массива строк, а просто в цикле добавляли по строке в листбокс
<mikekaganski> теперь мы слегка подрихтуем нашу FillFontsList
<mikekaganski> Мы перед циклом создадим массив, в цикле его заполним (вместо добавления в листбокс), после цикла отсортируем, а потом одним движением запихнём в листбокс
<mikekaganski> Для создания массива нужно, как и раньше, воспользоваться оператором Dim
<mikekaganski> но, поскольку это массив, мы должны указать его границы
<mikekaganski> Dim sFonts(LBound(oFonts()) to UBound(oFonts())) As String
<kompi> угу
<mikekaganski> Эта строка (которую помести после того, как ты получил oFonts) делает следующее: объявляет переменную sFonts - массив с индексами, такими же, как у oFonts
<mikekaganski> но это массив именно строк, а не объектов-описателей шрифтов, как oFonts
<kompi> афк 5 мин
<mikekaganski> ок
<kompi> здесь
<kompi> mikekaganski: ^
<mikekaganski> ок
<mikekaganski> Итак: теперь, вместо того, чтобы в цикле добавлять строки в листбокс, мы будем добавлять их в наш массив
<mikekaganski> здесь будет твоё долгожданное присвоение
<kompi> =)
<mikekaganski> sFonts(i) = oFonts(i).Name
<mikekaganski> В элемент массива строк (с индексом i ) мы записываем имя шрифта из oFonts (с тем же индексом)
<mikekaganski> вопросы?
<kompi> это ясно
<mikekaganski> ок
<kompi> и теперь мы имеем массив
<mikekaganski> после цикла (т.е. после Next) мы вызовем тот самый quicksort
<mikekaganski> quicksort(sFonts, LBound(sFonts()), UBound(sFonts())
<mikekaganski> то есть мы передаём в процедуру сам список, его наименьший и его наибольший индексы
<mikekaganski> По русски это как-то так: "отсортируй список от первого до последнего элемента, т.е. весь"
<kompi> в названии процедуры ничего менять не надо?
<mikekaganski> зачем?
<kompi> хм
<kompi> у нас сейчас так Sub FillFontsList(oListBox)
<kompi> вот это вот в скобках oListBox ни на что не влияет?
<mikekaganski> пока нет
<kompi> мне нравится это твое (пока)
<kompi> афк
<mikekaganski> мы же сортируем пока не листбокс, а массив, который мы заполняли в цикле
<mikekaganski> листбокс мы пока не трогали
<mikekaganski> Ну, и последним действием - то, что тебе хотелось: добавление всего полученного списка в листбокс: oListBox.AddItems(sFonts, 0)
<kompi> тут
<mikekaganski> Теперь мы пользуемся не oListBox.AddItem (как раньше), а oListBox.AddItems
<mikekaganski> в отличие от первой, вторая добавляет не одну строку, а массив строк
<mikekaganski> и добавляем мы этот массив в самое начало (начиная с индекса 0)
<mikekaganski> собственно, пока всё
<kompi> угу
<kompi> ошибка в сортировщике
<mikekaganski> где это?
<mikekaganski> а, да
<mikekaganski> я забыл
<mikekaganski> это тоже часть сортировщика, сорри
<kompi> а куда это засунуть?
<mikekaganski> перед сортировщиком
<kompi> работает
<kompi> осталась проблема дублирования
<mikekaganski> всё, должно решить проблему номер два - всё должно быть отсортировано
<mikekaganski> да
<mikekaganski> для этого нужна ещё одна функция - фильтрация уникальных. Вот тебе она: https://pastebin.ca/3955784
<mikekaganski> Она принимает отсортированный массив, фильтрует уникальные, и возвращает результат
<mikekaganski> чтобы воспользоваться ей, достаточно заменить oListBox.AddItems(sFonts, 0) на oListBox.AddItems(Unique(sFonts), 0)
<mikekaganski> и всё
<mikekaganski> Мы решили все три проблемы, но всё ещё не умеем не менять шрифты (только размер)
<kompi> мы...
<mikekaganski> ну, я надеюсь, тебе в принципе понятно, что мы делали
<kompi> а какие есть варианты не менять шрифты?
<kompi> мне понятно что мы сделали
<mikekaganski> а шрифты у тебя меняются где?
<kompi> в выпадающем списке
<mikekaganski> Я говорю о замене шрифтов в формулах
<kompi> в Formatting
<mikekaganski> именно
<mikekaganski> Obj1.FontName***=sFontName
<kompi> ага
<mikekaganski> так вот, можно эти четыре действия выполнять, только если имя шрифта не пустое
<mikekaganski> обрамить их условием
<mikekaganski> If (Len(sFontName)>0) Then
<mikekaganski> ...
<mikekaganski> End If
<kompi> а может сделать в диалоге чекбокс?
<kompi> и ссылаться на него?
<mikekaganski> зачем?...
<mikekaganski> ну, можно и так, почему нет
<mikekaganski> я бы просто добавил в список первый элемент - пустой
<kompi> чтобы юзер явно видел, что шрифты не активны и не меняются
<mikekaganski> но и с чекбоксом тоже можно
<mikekaganski> Первый элемент можно было бы даже назвать "<НЕ МЕНЯТЬ>"
<kompi> ну или так да с Вариантом "Do not change"
<kompi> =)
<kompi> давай с Не менять
<kompi> если тебе не надоело еще это
<mikekaganski> сорри, воз афк
<mikekaganski> энд гоуинг то гоу шортли
<kompi> хм
<kompi> ты пошел?
<mikekaganski> значит, так: для того, чтобы добавить нефункциональный элемент в начало списка, давай ещё подрихтуем FillFontsList
<mikekaganski> в самом начала добавим одну строку, вот так: oListBox.AddItem("<=НЕ МЕНЯТЬ=>", 0)
<mikekaganski> а в конце, где мы добавляем отсортированные строки, будем их пихать не в позицию 0, а в позицию 1 (т.е., после первой спецстроки)
<kompi> угу
<kompi> есть такое дело
<kompi> но будет ли он обрабатывать это, как "не изменять шрифт в формуле"?
<mikekaganski> теперь нам нужно отследить, когда выделен этот элемент
<mikekaganski> для этого добавим проверку в Formatting
<mikekaganski> у тебя там есть строка, которая получает имя шрифта из диалога
<mikekaganski> что-то вроде sFontName = Trim(oDialog.GetControl("ListBox1").SelectedItem)
<mikekaganski> так вот, после неё давай проверим номер выделенной строки в листбоксе
<kompi> sTypeFont=oDialog1.GetControl("ListTypeFonts").SelectedItem
<kompi> трим нету...
<mikekaganski> ок, да
<mikekaganski> неважно, я свои эксперименты делал
<mikekaganski> это делается с помощью функции GetSelectedItempos()
<mikekaganski> Давай добавим такое условие:
<mikekaganski> If (oDialog1.GetControl("ListTypeFonts").GetSelectedItempos() < 1) Then
<mikekaganski> sTypeFont = ""
<mikekaganski> End If
<mikekaganski> вот и всё
<kompi> в какую позицию?
<mikekaganski> как я и сказал - после той строки
<kompi> не работает, ошибка
<kompi> пойду поем, афк
mkaganski|mob has joined #libreoffice-ru
<mkaganski|mob> Здрасьте, а всё, что я писал про условие?
<mkaganski|mob> Про обрамление этих четырех строк?
<kompi> mkaganski|mob: так есть там условие твое один в один
<kompi> он же присваивает пустой шрифт потом, а вовсе не отменяет действие
<mkaganski|mob> Перечитай с 16:45
<kompi> блин, так я подумал, что это не нужно же, потому что потом ты присваиваешь пустое имя шрифта
<kompi> зачем тогда эти движения, если мы просто по номеру позиции уберем операцию?
<kompi> зато так не меняется шрифт вообще
<mikekaganski> не понял
<kompi> смотри, может я не так сделал, щас на пастебин засуну
<mikekaganski> sFontName или sTypeFont? Ты ж смотри
<mikekaganski> это именно то, о чём я говорил вчера
<mikekaganski> лучше использовать Option Explicit
<mikekaganski> у тебя ж переменная называется sTypeFont
<kompi> погоди
<kompi> да, сори
<kompi> все ОК, работает
<mikekaganski> :)
<mikekaganski> для этого мы и делали все те движения
<kompi> я вот думаю
<kompi> с точки зрения юзабельности, лучше чекбокс или лучше до нот чейндж
<mikekaganski> а есть много способов сделать одно и то же :)
<mikekaganski> и учти: если ты хочешь чекбокс, то его отключение должно делать листбокс неактивным
<kompi> конечно!
<kompi> в этом и суть
<mikekaganski> так что некоторые вещи, являясь практически идентичными с тз юзабилити, очень неидентичны для программирования
<kompi> убрал чекбокс, сделать с текущим шрифтом ничешго нельзя
<mikekaganski> на мой взгляд, это глупости
<mikekaganski> если пользователю всё понятно, глупо считать, на сколько десятых процента одно понятнее другого
<mikekaganski> а многие тупо этим и заняты
<kompi> хз
<kompi> mikekaganski: я так понимаю, сейчас мы берем текущий документ и весь его проверяем на предмет "Это формула Math?", если да, то шаманим, если нет, то чекаем следующий объект, так?
<mikekaganski> именно
<kompi> чтобы чекать только некий выделенный диапазон в документе наверняка есть какой-то простой метод?
<mikekaganski> а продолжение (обработка выделения) - в следующем номере :)
<kompi> ахаха
<kompi> ок
<kompi> тут наверное придется с чекбоксом выделываться, это ж другой вариант...или радиокнопки...
<kompi> э?
<kompi> mikekaganski: меня смущает зависон либры при инсталле расширения, вот это беда реальная
<mikekaganski> это я не могу ничего сказать
<kompi> тут нужна статистика
<kompi> mikekaganski: хе, вылезла проблема
<kompi> изменил шрифт на 40
<kompi> а фу
<kompi> это шрифт дежа вю идиотский специальный
<kompi> либра упала
<kompi> ...
kompi has quit [Quit: Page closed]
mkaganski|mob has quit [Read error: Connection reset by peer]
JohnDoe_71Rus has quit [Quit: KVIrc 4.9.3 Aria http://www.kvirc.net/]