From 440c6b5ab0759b76efbb19cf8dea4089bc7d66f9 Mon Sep 17 00:00:00 2001 From: Manuel Simon Hirsig Date: Tue, 2 Aug 2016 02:06:09 +0200 Subject: [PATCH] big filter refactoring, filter tab changes --- tabs/search/core.lua | 180 +++++++++++++++++++++++++---------------- tabs/search/frames.lua | 24 ++---- util/filter.lua | 51 ++++++++++-- 3 files changed, 163 insertions(+), 92 deletions(-) diff --git a/tabs/search/core.lua b/tabs/search/core.lua index 368f6cc..deefeb6 100644 --- a/tabs/search/core.lua +++ b/tabs/search/core.lua @@ -133,21 +133,15 @@ function public.set_filter(filter_string) m.search_box:SetText(filter_string) end -function private.add_filter(filter_string, replace) - filter_string = filter_string or m.get_form_filter() +function public.add_filter(filter_string) + local old_filter_string = m.search_box:GetText() + old_filter_string = Aux.util.trim(old_filter_string) - - local old_filter_string - if not replace then - old_filter_string = m.search_box:GetText() - old_filter_string = Aux.util.trim(old_filter_string) - - if strlen(old_filter_string) > 0 then - old_filter_string = old_filter_string..';' - end + if old_filter_string ~= '' then + old_filter_string = old_filter_string..';' end - m.search_box:SetText((old_filter_string or '')..filter_string) + m.search_box:SetText(old_filter_string..filter_string) end function private.update_auto_buy_filter() @@ -187,56 +181,6 @@ function private.clear_form() UIDropDownMenu_ClearAll(m.quality_dropdown) end -function private.get_form_filter() - local filter_term = '' - - local function add(part) - filter_term = filter_term == '' and part or filter_term..'/'..part - end - - add(m.name_input:GetText()) - - if m.exact_checkbox:GetChecked() then - add('exact') - end - - local min_level = m.blizzard_level(m.min_level_input:GetText()) - if min_level then - add(min_level) - end - - local max_level = m.blizzard_level(m.min_level_input:GetText()) - if max_level then - add(max_level) - end - - if m.usable_checkbox:GetChecked() then - add('usable') - end - - local class = UIDropDownMenu_GetSelectedValue(m.class_dropdown) ~= 0 and UIDropDownMenu_GetSelectedValue(m.class_dropdown) - if class then - local classes = { GetAuctionItemClasses() } - add(strlower(classes[class])) - local subclass = UIDropDownMenu_GetSelectedValue(m.subclass_dropdown) ~= 0 and UIDropDownMenu_GetSelectedValue(m.subclass_dropdown) - if subclass then - local subclasses = {GetAuctionItemSubClasses(class)} - add(strlower(subclasses[subclass])) - local slot = UIDropDownMenu_GetSelectedValue(m.slot_dropdown) ~= 0 and UIDropDownMenu_GetSelectedValue(m.slot_dropdown) - if slot then - add(strlower(getglobal(slot))) - end - end - end - - local quality = UIDropDownMenu_GetSelectedValue(m.quality_dropdown) >= 0 and UIDropDownMenu_GetSelectedValue(m.quality_dropdown) - if quality then - add(strlower(getglobal('ITEM_QUALITY'..quality..'_DESC'))) - end - - return filter_term -end - function private.discard_continuation() Aux.scan.abort(m.search_scan_id) m.current_search().continuation = nil @@ -798,19 +742,117 @@ function private.initialize_filter_dropdown() end end -function private.import_query_string() +function private.get_form() + local query_string = '' + local function add(part) + query_string = query_string == '' and part or query_string..'/'..part + end + + add(m.name_input:GetText()) + + if m.exact_checkbox:GetChecked() then + add('exact') + end + + local min_level = m.blizzard_level(m.min_level_input:GetText()) + if min_level then + add(min_level) + end + + local max_level = m.blizzard_level(m.min_level_input:GetText()) + if max_level then + add(max_level) + end + + if m.usable_checkbox:GetChecked() then + add('usable') + end + + local class = UIDropDownMenu_GetSelectedValue(m.class_dropdown) ~= 0 and UIDropDownMenu_GetSelectedValue(m.class_dropdown) + if class then + local classes = { GetAuctionItemClasses() } + add(strlower(classes[class])) + local subclass = UIDropDownMenu_GetSelectedValue(m.subclass_dropdown) ~= 0 and UIDropDownMenu_GetSelectedValue(m.subclass_dropdown) + if subclass then + local subclasses = {GetAuctionItemSubClasses(class)} + add(strlower(subclasses[subclass])) + local slot = UIDropDownMenu_GetSelectedValue(m.slot_dropdown) ~= 0 and UIDropDownMenu_GetSelectedValue(m.slot_dropdown) + if slot then + add(strlower(getglobal(slot))) + end + end + end + + local quality = UIDropDownMenu_GetSelectedValue(m.quality_dropdown) + if quality and quality >= 0 then + add(strlower(getglobal('ITEM_QUALITY'..quality..'_DESC'))) + end + + return query_string +end + +function private.set_form(filters) + + local class_index, subclass_index + + for _, filter in filters do + if filter[1] == 'name' then + m.name_input:SetText(filter[2]) + elseif filter[1] == 'exact' then + m.exact_checkbox:SetChecked(true) + elseif filter[1] == 'min_level' then + m.min_level_input:SetText(tonumber(filter[2])) + elseif filter[1] == 'max_level' then + m.max_level_input:SetText(tonumber(filter[2])) + elseif filter[1] == 'usable' then + m.usable_checkbox:SetChecked(true) + elseif filter[1] == 'class' then + class_index = Aux.info.item_class_index(filter[2]) + UIDropDownMenu_Initialize(m.class_dropdown, m.initialize_class_dropdown) -- TODO, wtf, why is this needed + UIDropDownMenu_SetSelectedValue(m.class_dropdown, class_index) + elseif filter[1] == 'subclass' then + subclass_index = Aux.info.item_subclass_index(class_index, filter[2]) + UIDropDownMenu_Initialize(m.subclass_dropdown, m.initialize_subclass_dropdown) -- TODO, wtf, why is this needed + UIDropDownMenu_SetSelectedValue(m.subclass_dropdown, subclass_index) + elseif filter[1] == 'slot' then + UIDropDownMenu_Initialize(m.slot_dropdown, m.initialize_slot_dropdown) -- TODO, wtf, why is this needed + UIDropDownMenu_SetSelectedValue(m.slot_dropdown, Aux.info.item_slot_index(class_index, subclass_index, filter[2])) + elseif filter[1] == 'quality' then + UIDropDownMenu_Initialize(m.quality_dropdown, m.initialize_quality_dropdown) -- TODO, wtf, why is this needed + UIDropDownMenu_SetSelectedValue(m.quality_dropdown, Aux.info.item_quality_index(filter[2])) + end + end +end + +function private.import_query_string() + local components, error = Aux.filter.parse_query_string(m.search_box:GetText()) + if components then + m.set_form(components.blizzard) + m.post_components = components.post + m.filter_display:SetText(Aux.filter.indented_post_query_string(m.post_components)) + else + Aux.log(error) + end end function private.export_query_string() - + local components, error = Aux.filter.parse_query_string(m.get_form()) + if components then + m.search_box:SetText(Aux.filter.query_string({blizzard=components.blizzard, post=m.post_components})) + m.clear_form() + m.post_components = {} + m.filter_display:SetText('') + else + Aux.log(error) + end end -private.post_query = {} +private.post_components = {} function private.add_post_filter() local name = UIDropDownMenu_GetSelectedValue(m.filter_dropdown) - if name then + if name and not strfind(Aux.filter.indented_post_query_string(m.post_components), '|n', 20) then local filter = name if Aux.filter.filters[name] and Aux.filter.filters[name].input_type ~= '' then filter = filter..'/'..m.filter_input:GetText() @@ -819,10 +861,12 @@ function private.add_post_filter() local components, error, suggestions = Aux.filter.parse_query_string(filter) if components then - tinsert(m.post_query, components[1]) - m.filter_display:SetText(Aux.filter.indented_post_query_string(m.post_query)) + tinsert(m.post_components, components.post[1]) + m.filter_display:SetText(Aux.filter.indented_post_query_string(m.post_components)) m.filter_input:SetText('') m.filter_input:ClearFocus() + else + Aux.log(error) end end end diff --git a/tabs/search/frames.lua b/tabs/search/frames.lua index 01f854b..c599fb4 100644 --- a/tabs/search/frames.lua +++ b/tabs/search/frames.lua @@ -344,9 +344,7 @@ Aux.search_tab.FRAMES(function(m, public, private) btn1:SetHeight(24) btn1:SetText('Search') btn1:SetScript('OnClick', function() - m.search_box:SetText('') - m.add_filter() - m.clear_form() + m.export_query_string() m.execute() end) @@ -354,21 +352,15 @@ Aux.search_tab.FRAMES(function(m, public, private) btn2:SetPoint('LEFT', btn1, 'RIGHT', 5, 0) btn2:SetWidth(80) btn2:SetHeight(24) - btn2:SetText('Add') - btn2:SetScript('OnClick', function() - m.add_filter() - m.clear_form() - end) + btn2:SetText('Export') + btn2:SetScript('OnClick', m.export_query_string) local btn3 = Aux.gui.button(m.frame.filter, 16) btn3:SetPoint('LEFT', btn2, 'RIGHT', 5, 0) btn3:SetWidth(80) btn3:SetHeight(24) - btn3:SetText('Replace') - btn3:SetScript('OnClick', function() - m.add_filter(nil, true) - m.clear_form() - end) + btn3:SetText('Import') + btn3:SetScript('OnClick', m.import_query_string) end do local editbox = Aux.gui.editbox(m.frame.filter) @@ -519,7 +511,7 @@ Aux.search_tab.FRAMES(function(m, public, private) Aux.gui.vertical_line(m.frame.filter, 332) do local dropdown = Aux.gui.dropdown(m.frame.filter) - dropdown:SetPoint('TOPRIGHT', -200, -10) + dropdown:SetPoint('TOPRIGHT', -210, -10) dropdown:SetWidth(170) dropdown:SetHeight(10) UIDropDownMenu_Initialize(dropdown, m.initialize_filter_dropdown) @@ -553,8 +545,8 @@ Aux.search_tab.FRAMES(function(m, public, private) end do local label = Aux.gui.label(m.frame.filter, 13) - label:SetPoint('TOPLEFT', 340, -50) - label:SetWidth(200) + label:SetPoint('TOPLEFT', 350, -53) + label:SetWidth(300) label:SetJustifyH('LEFT') private.filter_display = label end diff --git a/util/filter.lua b/util/filter.lua index 275e216..e882907 100644 --- a/util/filter.lua +++ b/util/filter.lua @@ -227,6 +227,7 @@ function private.operator(str) end function private.blizzard_filter_parser() + local class_index, subclass_index local filters = {} return function(str, first) local filter @@ -242,18 +243,20 @@ function private.blizzard_filter_parser() return nil, 'Erroneous level range modifier' end elseif Aux.info.item_class_index(str) and not (filters.class and not filters.subclass and str == strlower(({ GetAuctionItemClasses() })[10])) then + class_index = Aux.info.item_class_index(str) if not filters.class then filter = {'class', str} else return nil, 'Erroneous item class modifier' end - elseif filters.class and Aux.info.item_subclass_index(Aux.info.item_class_index(filters.class), str) then + elseif class_index and Aux.info.item_subclass_index(class_index, str) then + subclass_index = Aux.info.item_subclass_index(class_index, str) if not filters.subclass then filter = {'subclass', str} else return nil, 'Erroneous item subclass modifier' end - elseif filters.subclass and Aux.info.item_slot_index(Aux.info.item_class_index(filters.class), Aux.info.item_subclass_index(Aux.info.item_class_index(filters.class), filters.subclass), str) then + elseif subclass_index and Aux.info.item_slot_index(class_index, subclass_index, str) then if not filters.slot then filter = {'slot', str} else @@ -466,15 +469,17 @@ function private.suggestions(components) end -- subclasses - if blizzard_filters.class and not blizzard_filters.subclass then - for _, subclass in ipairs({ GetAuctionItemSubClasses(Aux.info.item_class_index(blizzard_filters.class)) }) do + local class_index = Aux.info.item_class_index(blizzard_filters.class or '') + if class_index and not blizzard_filters.subclass then + for _, subclass in ipairs({ GetAuctionItemSubClasses(class_index) }) do tinsert(suggestions, subclass) end end -- slots - if blizzard_filters.class and blizzard_filters.subclass and not blizzard_filters.slot then - for _, invtype in ipairs({ GetAuctionInvTypes(Aux.info.item_class_index(blizzard_filters.class), Aux.info.item_subclass_index(Aux.info.item_class_index(blizzard_filters.class), blizzard_filters.subclass)) }) do + local subclass_index = Aux.info.item_subclass_index(class_index, blizzard_filters.subclass or '') + if subclass_index and not blizzard_filters.slot then + for _, invtype in ipairs({ GetAuctionInvTypes(class_index, Aux.info.item_subclass_index(Aux.info.item_class_index(blizzard_filters.class), blizzard_filters.subclass)) }) do tinsert(suggestions, getglobal(invtype)) end end @@ -501,20 +506,50 @@ function private.suggestions(components) return suggestions end +function public.query_string(components) + local prettified = m.query_builder() + + local blizzard_filters = {} + for _, filter in components.blizzard do + prettified.append((filter[2] or filter[1])) + end + + for _, component in components.post do + if component[1] == 'operator' then + local suffix = '' + if not component[3] then + suffix = '*' + elseif component[3] > 2 then + suffix = component[3] + end + prettified.append(component[2]..suffix) + elseif component[1] == 'filter' then + prettified.append(component[2]) + if component[3] then + prettified.append(component[3]) + end + end + end + + return prettified.get() +end + function public.indented_post_query_string(components) + local no_line_break local stack = {} local str = '' - for _, component in components.post do + for _, component in components do if str ~= '' then - str = str..'|n' + str = str..(no_line_break and ' ' or '|n') end for _=1,getn(stack) do str = str..' ' end if component[1] == 'operator' and component[2] then + no_line_break = component[2] == 'not' local suffix = '' if not component[3] then suffix = '*'