![]() |
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]() ![]() ![]() |
|
former |
|
|||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 5 Всего: 17 |
Внимательно читал статью Quadr0, искал на форуме и в инете, но так решение своего вопроса и не нашел. Опыт работы с VST у меня не большой, поэтому надеюсь на вашу помощь форумчане.
Что бы было понятно в чем проблема, в качестве примера буду использовать пользователей, компьютеры и права. Итак. Имеется три дерева VST. Первое дерево имеет следующую структуру (3-уровня): - Пользователь_1 (корневой элемент, грузится из таблицы Users БД) |-Компьютеры (создается для каждого пользователя) |-Компьютер_1 (грузится из таблицы-связи UserComp БД) |-Компьютер_2 (грузится из таблицы-связи UserComp БД) |-Компьютер_3 (грузится из таблицы-связи UserComp БД) ... |-Компьютер_N (грузится из таблицы-связи UserComp БД) |-Права (создается для каждого пользователя) |-Право_1 (грузится из таблицы-связи UserPermiss БД) |-Право_2 (грузится из таблицы-связи UserPermiss БД) |-Право_3 (грузится из таблицы-связи UserPermiss БД) ... |-Право_N (грузится из таблицы-связи UserPermiss БД) ... - Пользователь_N (корневой элемент, грузится из таблицы Users БД) Второе дерево имеет следующую структуру (1-уровень): - Компьютер_1 (корневой элемент, грузится из таблицы Computers БД) - Компьютер_2 (корневой элемент, грузится из таблицы Computers БД) ... - Компьютер_N (корневой элемент, грузится из таблицы Computers БД) Третье дерево имеет следующую структуру (1-уровень): - Право_1 (корневой элемент, грузится из таблицы Permissions БД) - Право_2 (корневой элемент, грузится из таблицы Permissions БД) ... - Право_N (корневой элемент, грузится из таблицы Permissions БД) Вопросов по построению и изменению элементов дерева не возникает, равно как и чтению/записи в БД. Единственно что не знаю как реализовать, так это копирование элементов из деревьев 2 и 3 в 1 с помощью Drag&Drop, которое должно осуществляться следующим образом: - при переносе в уровень "Пользователь" (1-й), пункт должен записываться дочерним элементом уровня "Компьютеры" (2-й) или "Права" (2-й), в зависимости от дерева-источника. - при переносе в уровни "Компьютеры" (2-й) или "Права" (2-й), независимо от дерева-источника, пункт должен записываться дочерним элементом соответствующего уровня "Компьютеры" (2-й) или "Права" (2-й), в зависимости от дерева-источника. Проще говоря, что бы компьютеры попадали в "Компьютеры," а права в "Права", соответствующего пользователя. Как это реализовать? Запись элемента имеет следующий вид:
Это сообщение отредактировал(а) former - 24.2.2010, 16:52 -------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
|||
|
||||
former |
|
|||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 5 Всего: 17 |
up
-------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
|||
|
||||
kami |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 23 Всего: 72 |
Я правильно понял, что в первом дереве:
в уровне 1 - только пользователи в уровне 2 - "корневой" элемент "компьютеры" или "права", являющийся просто заголовком в уровне 3 - имя компьютера или имя права. Кроме уровня вложенности есть ли отличия? К примеру - нельзя ли в TVSTRecord внести поле elType=(etUser, etRootPC, etRootRights, etPC, etRight) ? |
|||
|
||||
former |
|
|||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 5 Всего: 17 |
kami, именно так.
Я об этом варианте думал, правда в другом формате (U,C,P,UC,UP), но проблема моя состоит в самой реализации событий OnDragDrop и OnDragOver. Если я правильно понял, то в этих событиях необходимо читать данные DropTargetNode. Так? -------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
|||
|
||||
kami |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 23 Всего: 72 |
Да без разницы как, главное - мы друг друга поняли ![]()
В статье Quadro, пункт 3.0 этот процесс очень хорошо описан. Если вкратце - то да, + Source.GetSortedSelection. Главное - не перепутать типы NodeData из дерева 2 и 3 ![]() Это сообщение отредактировал(а) kami - 26.2.2010, 00:36 |
|||
|
||||
former |
|
|||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 5 Всего: 17 |
kami, не понимаю, где определять, куда нужно добавить нод.
Присоединённый файл ( Кол-во скачиваний: 20 ) ![]() -------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
|||
|
||||
kami |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 23 Всего: 72 |
Код я написал. Правда, я видимо пользуюсь более новой версией VT - не совпали типы событий OnGetText, пришлось их чуть подправить, чтобы запускались у меня на компьютере. Думаю, большого труда исправить обратно не составит.
Кстати, зря проигнорировал мое предложение сделать ElType - перечисляемым (или как они называются, не помню) типом. Определять тип строкой - для этого должны быть очень веские основания, т.к. обработка строк занимает гораздо больше времени, уменьшается удобочитаемость, приходится задействовать кучу if вместо одного case и так далее... Собственно, код во вложении, с достаточно подробными комментариями... Объявлено событие OnDragOver; в дереве компьютеров DragMode=dmAutomatic, DragType=dtOLE. Вроде всё, но лучше посмотреть самому. Это сообщение отредактировал(а) kami - 1.3.2010, 01:42 Присоединённый файл ( Кол-во скачиваний: 22 ) ![]() |
|||
|
||||
former |
|
|||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 5 Всего: 17 |
У меня 4.8.6. Вроде бы последняя. Согласен. Поправлю. Большое спасибо за помощь (+). Буду разбираться. Если появятся вопросы, отпишу. -------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
|||
|
||||
former |
|
|||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 5 Всего: 17 |
kami, остается непонятным, где нужно осуществлять запись в БД при перетаскивании. Понимаю, что до перетаскивания, что бы в случае ошибки можно было откатить транзакцию и отменить копирование записи.
Решил прислушаться к твоим комментариям. Кое что уже поправил. Теперь ломаю голову над тем, как разрешить копировать нод только в ту ветку, где он должен находиться. Это сообщение отредактировал(а) former - 2.3.2010, 19:38 -------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
|||
|
||||
kami |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 23 Всего: 72 |
Вот по поводу БД - не ко мне, вообще не соображаю в них.
Тогда - до
так как именно он добавляет нод к главному списку. А почему должна возникнуть ошибка? |
||||
|
|||||
former |
|
|||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 5 Всего: 17 |
Вот как я рассуждаю. Есть три таблицы в БД: Пользователи, Компьютеры и Компьютеры пользователей. Дерево пользователей и их компьютеров грузится в первый VST, а компьютеров - во второй VST. После того как выполнен Drop (при попытке добавить компьютер пользователю), должна быть выполнена попытка записи в таблицу Компьютеры пользователей и только после этого выполнено изменение в дереве пользователей. Ошибка может возникнуть при записи в БД в нескольких случаях: - пропало соединение с сервером (для сетевой БД) - отсутствуют права на определенную операцию с БД - данный компьютер уже присутствует в списке пользователя ну и т.п. Добавлено через 4 минуты и 40 секунд У набора данных UCompDataS (Компьютеры пользователей) есть событие AfterPost (действия после записи) вот в нем и нужно давать разрешение на вставку нода в дерево, а в событии OnPostError - наоборот запрещать. -------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
|||
|
||||
kami |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 23 Всего: 72 |
Это синхронные или асинхронные события? В смысле, если добавление данных осуществить в OnDragDrop - что будет раньше - одно из этих событий, или end DragDrop?
Первые 2 - согласен, есть такое дело. Третье можно (и имхо, нужно ибо будет в тыщу раз быстрее, чем операция с БД) обрабатывать непосредственно при добавлении. |
||||
|
|||||
former |
|
|||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 5 Всего: 17 |
Механизм следующий: В тот момент, когда бросают нод при переносе, осуществляется попытка записи данных в БД (вызывается метод Post). В случае ошибки возникает событие OnPostError. Если запись выполнена успешно, то выполняется AfterPost. Вот именно в AfterPost необходимо добавлять этот нод в дерево. Таким образом независимо от ошибки (перечисленных ранее) при сохранении данных в БД, нод будет добавлен только в случае успешного Post. Т.е. может быть код DragDrop перенесен в AfterPost? -------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
|||
|
||||
kami |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 23 Всего: 72 |
Да без проблем. Нужно только где-то сохранить SourceNodeData и TargetNode ( то, которое до vt.InsertNode). И все-таки ты не ответил на мой вопрос (это уже чисто из любопытства) - если добавлять элемент в БД из события OnDragDrop, что будет раньше - вызовется событие OnAfterPost или же до него будет выход из OnDragDrop ? Добавлено через 2 минуты и 20 секунд Таким образом - убираем из кода vt.InsertNode и всё после него. Сохраняем указанные выше параметры. Вместо убранного - добавляем данные в базу данных. В OnAfterPost пишем всё, что удалили из OnDragDrop. |
|||
|
||||
former |
|
|||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 5 Всего: 17 |
Сначала OnAfterPost потом выход из OnDragDrop.
-------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
|||
|
||||
kami |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 23 Всего: 72 |
||||
|
||||
kami |
|
||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 23 Всего: 72 |
Не вижу проблемы. Это реализуется в OnDragOver. Примерный алгоритм (возможны варианты, код будет очень похож на OnDragDrop). Для простоты считаем, что выделить и перебросить несколько элементов сразу невозможно. берем DropTargetNode и соответствующий ему TargetNodeData берем SourceNodes[0] (если есть, конечно) и соответствующий ему SourceNodeData Смотрим на Mode: TDropMode
Это гарантирует, что "внутрь" нода, над которым висит на данный момент курсор попадут только "свои" данные. Причем - если мы над "пользователем", то разрешаем всё. Если внутри какого-нибудь из списков (т.е. над элементом 3-го уровня) - то "так низзя". Иначе (Mode<>dmOnNode) - пользователь пытается воткнуть новый нод между элементами. По логике это возможно только в том случае, если мы пытаемся воткнуться между элементами третьего уровня (т.е. компьютер - между компами, уже находящимися в списке "Компьютеры" этого пользователя, для прав - то же самое). Тут гораздо проще
![]() Это сообщение отредактировал(а) kami - 3.3.2010, 00:51 |
||||||
|
|||||||
former |
|
||||||||||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 5 Всего: 17 |
kami, реализовал!
Переменные сделал глобальными.
OnDragDrop:
OnDragOver:
Запись данных в БД:
Добавление нода в дерево, если запись в БД успешна:
Вот только не понятно, что будет, если изменится количество нодов во втором уровне. -------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
||||||||||
|
|||||||||||
kami |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 23 Всего: 72 |
А ничего страшного не будет ![]() Добавить новые типы в TElType и добавить "свои" условия в по аналогии с уже добавленными. |
|||
|
||||
former |
|
||||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 5 Всего: 17 |
Я имел виду в функции GetNeededNode.
Вот на этом участке:
Или с каждым новым нодом во 2-м уровне будет добавляться еще одна строка
-------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
||||
|
|||||
kami |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 23 Всего: 72 |
Это было бы неоптимально, т.к. может измениться не только количество, но и порядок их следования. Ну, давай подойдем к этой задаче так:
Само собой, это только один из возможных вариантов работы. В нем, например, не предусмотрена возможность поиска не только в дочерних элементах первого уровня; мне не нравится то, что здесь пришлось использовать Case, что уже снижает универсальность... но дальше как-то не думается на сегодняшний день... |
||||
|
|||||
former |
|
|||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 5 Всего: 17 |
kami, не думал о том, что бы расширить статью Quadr0?
-------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
|||
|
||||
kami |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1806 Регистрация: 25.8.2007 Где: Санкт-Петербург Репутация: 23 Всего: 72 |
Нет, а зачем? Там и так всё более чем расписано. Единственное, что мог бы предложить в статью или околостатьевый материал - процедуру печати, которая не обрезает строки посередине, а действует почти так, как организована печать в Excel. |
|||
|
||||
former |
|
|||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 5 Всего: 17 |
Это было бы интересно! ![]() -------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
|||
|
||||
Sed0Y |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 48 Регистрация: 16.1.2009 Репутация: нет Всего: нет |
Добавте лучше статью - пример как строить дерево с БД к типа (многоуровневая):
а то я уже запарился - никак не могу придумать и найти - плз |
|||
|
||||
former |
|
|||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 5 Всего: 17 |
Sed0Y, а поиском в соответствующем разделе (БД) воспользоваться не пробовал? -------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: Общие вопросы" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |