#!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*-
# ---------------------------------------------------------------------------##
#
# Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer
# Copyright (C) 2003 Mt. Hood Playing Card Co.
# Copyright (C) 2005-2009 Skomoroh
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# ---------------------------------------------------------------------------##

import os
import shutil
import tkinter
import tkinter.colorchooser
import tkinter.ttk as ttk
from pathlib import Path

from pysollib.mfxutil import KwStruct, USE_PIL
from pysollib.mygettext import _
from pysollib.resource import TTI, Tile
from pysollib.ui.tktile.selecttree import SelectDialogTreeData
from pysollib.ui.tktile.tkutil import bind
from pysollib.util import IMAGE_EXTENSIONS

from .selecttree import SelectDialogTreeCanvas
from .selecttree import SelectDialogTreeLeaf, SelectDialogTreeNode
from .tkwidget import MfxDialog, MfxMessageDialog, MfxScrolledCanvas, \
                      PysolButton, PysolCombo, PysolEntry, PysolNotebook


# ************************************************************************
# * Nodes
# ************************************************************************

class SelectTileLeaf(SelectDialogTreeLeaf):
    pass


class SelectTileNode(SelectDialogTreeNode):
    def _getContents(self):
        contents = []
        for obj in self.tree.data.all_objects:
            if self.select_func(obj):
                node = SelectTileLeaf(
                    self.tree, self, text=obj.name, key=obj.index)
                contents.append(node)
        return contents or self.tree.data.no_contents


# ************************************************************************
# * Tree database
# ************************************************************************

class SelectTileData(SelectDialogTreeData):
    def __init__(self, manager, key):
        SelectDialogTreeData.__init__(self)
        self.all_objects = manager.getAllSortedByName()
        self.all_objects = [obj for obj in self.all_objects if not obj.error]
        self.all_objects = [tile for tile in self.all_objects
                            if tile.index > 0 and tile.filename]
        self.no_contents = [SelectTileLeaf(
            None, None, _("(no tiles)"), key=None), ]
        # e1 = isinstance(key, str) or len(self.all_objects) <= 17
        # e2 = 0
        self.rootnodes = (
            SelectTileNode(
                None, _("All Backgrounds"),
                lambda tile: 1, expanded=0),
            SelectTileNode(
                None, _("Tiles"),
                lambda tile: os.path.basename(
                    os.path.dirname(tile.filename)) == 'tiles', expanded=0),
            SelectTileNode(
                None, _("Images"),
                lambda tile: (os.path.basename(
                    os.path.dirname(tile.filename)) in
                              ('stretch', 'save-aspect', 'stretch-4k',
                               'save-aspect-4k')), expanded=0),
            SelectTileNode(None, _("Solid Colors"), (
                SelectTileLeaf(None, None, _("Azure"), key="#0082df"),
                SelectTileLeaf(None, None, _("Black"), key="#000000"),
                SelectTileLeaf(None, None, _("Blue"), key="#0000ff"),
                SelectTileLeaf(None, None, _("Bronze"), key="#ce8946"),
                SelectTileLeaf(None, None, _("Brown"), key="#684700"),
                SelectTileLeaf(None, None, _("Cyan"), key="#00ffff"),
                SelectTileLeaf(None, None, _("Gold"), key="#ffd700"),
                SelectTileLeaf(None, None, _("Grey"), key="#888888"),
                SelectTileLeaf(None, None, _("Green"), key="#008200"),
                SelectTileLeaf(None, None, _("Lime"), key="#00ff00"),
                SelectTileLeaf(None, None, _("Magenta"), key="#ff00ff"),
                SelectTileLeaf(None, None, _("Navy"), key="#000086"),
                SelectTileLeaf(None, None, _("Olive"), key="#868200"),
                SelectTileLeaf(None, None, _("Orange"), key="#f79600"),
                SelectTileLeaf(None, None, _("Pink"), key="#ff92fc"),
                SelectTileLeaf(None, None, _("Purple"), key="#800080"),
                SelectTileLeaf(None, None, _("Red"), key="#ff0000"),
                SelectTileLeaf(None, None, _("Silver"), key="#c0c0c0"),
                SelectTileLeaf(None, None, _("Teal"), key="#008286"),
                SelectTileLeaf(None, None, _("Violet"), key="#8300ff"),
                SelectTileLeaf(None, None, _("White"), key="#ffffff"),
                SelectTileLeaf(None, None, _("Yellow"), key="#ffff00"),
            ), expanded=0),
        )


# ************************************************************************
# * Canvas that shows the tree
# ************************************************************************

class SelectTileTree(SelectDialogTreeCanvas):
    data = None


# ************************************************************************
# * Dialog
# ************************************************************************

class SelectTileDialogWithPreview(MfxDialog):
    Tree_Class = SelectTileTree
    TreeDataHolder_Class = SelectTileTree
    TreeData_Class = SelectTileData

    def __init__(self, parent, title, app, manager, key=None, **kw):
        kw = self.initKw(kw)
        MfxDialog.__init__(self, parent, title, kw.resizable, kw.default)
        top_frame, bottom_frame = self.createFrames(kw)
        self.createBitmaps(top_frame, kw)
        #
        if key is None:
            key = manager.getSelected()
        self.app = app
        self.manager = manager
        self.criteria = SearchCriteria()
        self.key = key
        self.table_color = app.opt.colors['table']
        if self.TreeDataHolder_Class.data is None:
            self.TreeDataHolder_Class.data = self.TreeData_Class(manager, key)
        #

        pw = parent.winfo_width()
        ph = parent.winfo_height()
        py = parent.winfo_y()
        px = parent.winfo_x()

        h = int(ph * .8)
        w = int(pw * .8)
        w1 = int(min(275, pw / 2.5))
        geometry = ("%dx%d+%d+%d" % (w, h, px + ((pw - w) / 2),
                                     py + (int((ph - h) / 1.5))))
        self.top.wm_minsize(400, 200)

        padx, pady = 4, 4

        paned_window = ttk.PanedWindow(top_frame, orient='horizontal')
        paned_window.pack(expand=True, fill='both', padx=8, pady=8)
        left_frame = ttk.Frame(paned_window)
        right_frame = ttk.Frame(paned_window)
        paned_window.add(left_frame)
        paned_window.add(right_frame)

        notebook = PysolNotebook(left_frame)
        notebook.grid(row=0, column=0, sticky='nsew',
                      padx=padx, pady=pady, columnspan=2)
        tree_frame = ttk.Frame(notebook)
        notebook.add(tree_frame, text=_('Tree View'))
        search_frame = ttk.Frame(notebook)
        notebook.add(search_frame, text=_('Search'))
        loadfile_frame = ttk.Frame(notebook)
        notebook.add(loadfile_frame, text=_('Import File'))

        font = app.getFont("default")
        padx, pady = 4, 4
        self.tree = self.Tree_Class(self, tree_frame, key=key,
                                    default=kw.default,
                                    font=font, width=w1)
        self.tree.frame.pack(padx=padx, pady=pady, expand=True, fill='both')

        # Search
        searchbox = ttk.Frame(search_frame)
        searchText = tkinter.StringVar()
        self.list_searchlabel = tkinter.Label(searchbox, text=_("Search:"),
                                              justify='left', anchor='w')
        self.list_searchlabel.pack(side="top", fill='both', ipadx=1)
        self.list_searchtext = PysolEntry(searchbox,
                                          fieldname=_("Search:"),
                                          textvariable=searchText)

        self.advSearch = PysolButton(searchbox, text='...',
                                     prefixtext=_("Advanced Search"),
                                     command=self.advancedSearch,
                                     width=2)
        self.advSearch.pack(side="right")

        self.list_searchtext.pack(side="top", fill='both',
                                  padx=padx, pady=pady, ipadx=1)
        searchText.trace_add('write', self.basicSearch)

        searchbox.pack(side="top", fill="both")

        self.list_scrollbar = tkinter.Scrollbar(search_frame)
        self.list_scrollbar.pack(side="right", fill='both')

        self.createBitmaps(search_frame, kw)
        self.list = tkinter.Listbox(search_frame, exportselection=False)
        self.list.pack(padx=padx, pady=pady, expand=True, side='left',
                       fill='both', ipadx=1)
        self.updateSearchList("")
        bind(self.list, '<<ListboxSelect>>', self.selectSearchResult)
        bind(self.list, '<FocusIn>',
             lambda e: self.app.speech.speak(_("Tiles list")))
        bind(self.list, '<FocusOut>',
             lambda e: self.list.selection_clear(0, 'end'))

        self.list.config(yscrollcommand=self.list_scrollbar.set)
        self.list_scrollbar.config(command=self.list.yview)

        if USE_PIL:
            self.scaleOptions = {"Default": 0,
                                 "Tile": 1,
                                 "Stretch": 2,
                                 "Preserve aspect ratio": 3}
            scaleValues = list(self.scaleOptions.keys())

            self.scaling = tkinter.StringVar()
            self.scaling.set(next(key for key, value in
                                  self.scaleOptions.items()
                             if value == app.opt.tabletile_scale_method))
            self.labelScale = tkinter.Label(left_frame,
                                            text=_("Image scaling:"),
                                            anchor="w")

            self.textScale = PysolCombo(left_frame, values=scaleValues,
                                        fieldname=_("Image scaling:"),
                                        state='readonly',
                                        textvariable=self.scaling,
                                        selectcommand=self.updateScaling)
            self.labelScale.grid(row=4, column=0, sticky='ew',
                                 padx=padx, pady=pady)
            self.textScale.grid(row=4, column=1, sticky='ew',
                                padx=padx, pady=pady)

        self.loadedFile = tkinter.StringVar()
        self.nameFile = tkinter.StringVar()
        self.fileScaling = tkinter.StringVar()
        self.loadFileButton = PysolButton(loadfile_frame,
                                          text=_('Select File...'),
                                          prefixtext=self.loadedFile.get(),
                                          command=self.loadFile)
        self.loadFileButton.grid(
                row=1, column=0, sticky='ew', padx=padx, pady=pady)
        self.fileLabelMaxLen = 26
        self.filelabel = tkinter.Label(loadfile_frame, text='',
                                       justify='left', anchor='w',
                                       width=self.fileLabelMaxLen)
        self.filelabel.grid(
                row=1, column=1, sticky='ew', padx=padx, pady=pady)

        self.labelLoadScale = tkinter.Label(loadfile_frame,
                                            text=_("Name:"),
                                            anchor="w")
        self.textLoadScale = PysolEntry(loadfile_frame, fieldname=_("Name:"),
                                        textvariable=self.nameFile)
        self.labelLoadScale.grid(row=2, column=0, sticky='ew',
                                 padx=padx, pady=pady)
        self.textLoadScale.grid(row=2, column=1, sticky='ew',
                                padx=padx, pady=pady)

        self.loadScaling = tkinter.StringVar()
        self.loadScaling.set(next(key for key, value in
                             self.scaleOptions.items()
                             if value == app.opt.tabletile_scale_method))
        self.labelLoadScale = tkinter.Label(loadfile_frame,
                                            text=_("Scaling:"),
                                            anchor="w")

        scaleValues2 = scaleValues.copy()
        scaleValues2.remove("Default")
        self.fileScaling.set(scaleValues2[0])

        self.textLoadScale = PysolCombo(loadfile_frame, values=scaleValues2,
                                        fieldname=_("Scaling:"),
                                        state='readonly',
                                        textvariable=self.fileScaling,
                                        selectcommand=self.updateLoadPreview)
        self.labelLoadScale.grid(row=3, column=0, sticky='ew',
                                 padx=padx, pady=pady)
        self.textLoadScale.grid(row=3, column=1, sticky='ew',
                                padx=padx, pady=pady)

        loadfile_preview_label = tkinter.Label(loadfile_frame,
                                               text=_("Preview:"), anchor="w")
        loadfile_preview_label.grid(row=4, column=0, columnspan=2, sticky='nw',
                                    padx=padx, pady=pady)

        # Container for preview so we can maintain aspect ratio
        loadfile_preview_container = ttk.Frame(loadfile_frame)
        loadfile_preview_container.grid(row=5, column=0, columnspan=2,
                                        sticky='nsew', padx=padx, pady=pady)
        self.loadfile_aspect_frame = ttk.Frame(loadfile_preview_container)
        self.previewLoad = MfxScrolledCanvas(self.loadfile_aspect_frame,
                                             hbar=0, vbar=0)
        self.previewLoad.canvas.preview = 1  # fill canvas, no margins
        self.previewLoad.frame.pack(fill='both', expand=True)

        def ResizePreview(event):
            # 16:9 to match most modern monitors
            height = 9
            width = 16

            c = loadfile_preview_container
            cw = event.width if event and getattr(event, 'width', None) \
                else c.winfo_width()
            if cw <= 1:
                return

            h = int(cw * height / width)
            loadfile_preview_container.configure(height=h)
            self.loadfile_aspect_frame.place(x=0, y=0, width=cw, height=h)

        loadfile_preview_container.bind('<Configure>', ResizePreview)

        def SetupPreview():
            loadfile_preview_container.update_idletasks()
            ResizePreview(None)

        loadfile_preview_container.after(50, SetupPreview)

        self.previewLoad.canvas.setTile(None)
        self.previewLoad.canvas.config(bg=self.app.opt.colors['table'])

        self.useFileButton = PysolButton(loadfile_frame, text=_('Import'),
                                         command=self.useFile)
        self.useFileButton.grid(row=6, column=0, sticky='w',
                                padx=padx, pady=pady)
        self.useFileButton.state(['disabled'])

        loadfile_frame.columnconfigure(0, weight=1)
        loadfile_frame.columnconfigure(1, weight=1)

        left_frame.rowconfigure(0, weight=1)
        left_frame.columnconfigure(0, weight=1)
        left_frame.columnconfigure(1, weight=1)

        self.preview = MfxScrolledCanvas(right_frame, hbar=0, vbar=0)
        self.preview.pack(side="right", fill='both', expand=True,
                          padx=padx, pady=pady)

        self.preview.canvas.preview = 1
        # create a preview of the current state
        self.preview_key = -1
        self.preview_scaling = -1
        self.current_key = -1
        self.updatePreview(key, app.opt.tabletile_scale_method)
        #
        focus = self.createButtons(bottom_frame, kw)
        focus = self.tree.frame

        self.mainloop(focus, kw.timeout, geometry=geometry)

    def destroy(self):
        self.tree.updateNodesWithTree(self.tree.rootnodes, None)
        self.tree.destroy()
        self.preview.unbind_all()
        MfxDialog.destroy(self)

    def initKw(self, kw):
        kw = KwStruct(kw,
                      strings=((_("&Solid color..."), 10),
                               'sep', _("&Select"), _("&Cancel"),),
                      default=0,
                      resizable=True,
                      font=None,
                      padx=10, pady=10,
                      )
        return MfxDialog.initKw(self, kw)

    def mDone(self, button):
        if button == 0:  # "OK" or double click
            if isinstance(self.tree.selection_key, str):
                self.key = str(self.tree.selection_key)
            else:
                self.key = self.tree.selection_key
            self.tree.n_expansions = 1  # save xyview in any case
        if button == 10:  # "Solid color..."
            try:
                c = tkinter.colorchooser.askcolor(
                    master=self.top,
                    initialcolor=self.table_color,
                    title=_("Select table color"))
            except tkinter.TclError:
                pass
            else:
                if c and c[1]:
                    color = str(c[1])
                    self.key = color.lower()
                    self.table_color = self.key
                    self.tree.updateSelection(self.key)
                    self.updatePreview(self.key)
            return
        MfxDialog.mDone(self, button)

    def basicSearch(self, *args):
        self.updateSearchList(self.list_searchtext.get())

    def updateScaling(self, *args):
        self.updatePreview(self.preview_key,
                           self.scaleOptions[self.scaling.get()])

    def updateLoadPreview(self, *args):
        filename = self.loadedFile.get()
        canvas = self.previewLoad.canvas
        if not filename or not os.path.isfile(filename):
            canvas.setTile(None)
            canvas.config(bg=self.app.opt.colors['table'])
            return
        scaling = self.fileScaling.get()
        stretch = 0
        save_aspect = 0
        if scaling == 'Stretch':
            stretch = 1
        elif scaling == 'Preserve aspect ratio':
            stretch = 1
            save_aspect = 1
        if canvas.setTile(filename, stretch, save_aspect):
            canvas.config(bg=self.app.top_bg)
            canvas.setTextColor(self.app.opt.colors['text'])
        else:
            canvas.setTile(None)
            canvas.config(bg=self.app.opt.colors['table'])

    def updateSearchList(self, searchString):
        self.criteria.name = searchString
        self.performSearch()

    def performSearch(self):
        self.list.delete(0, "end")
        self.list.vbar_show = True
        tiles = self.manager.getAllSortedByName()

        results = []
        for tile in tiles:
            if tile.name == 'None':
                continue

            if (self.criteria.type == "Images" and os.path.basename(
                    os.path.dirname(tile.filename)) not in
                    ('stretch', 'save-aspect', 'stretch-4k',
                     'save-aspect-4k')):
                continue
            if (self.criteria.type == "Tiles" and os.path.basename(
                    os.path.dirname(tile.filename)) != 'tiles'):
                continue
            if (self.criteria.size != ""
                    and self.criteria.sizeOptions[self.criteria.size]
                    != tile.size):
                continue

            if self.app.checkSearchString(self.criteria.name,
                                          tile.name):
                results.append(tile.name)
        results.sort(key=lambda x: x.lower())
        pos = 0
        for result in results:
            self.list.insert(pos, result)
            pos += 1

    def loadFile(self):
        filetypes = [
            ("All images", " ".join("%s" % type for type in IMAGE_EXTENSIONS)),
            *[(_("%s files") % type.upper(), "*" + type)
              for type in IMAGE_EXTENSIONS],
            ("All files", "*.*")
        ]

        d = tkinter.filedialog.Open()
        filename = d.show(filetypes=filetypes)
        if filename:
            self.loadedFile.set(filename)
            name = Path(filename).name
            if len(name) > self.fileLabelMaxLen:
                name = name[:self.fileLabelMaxLen - 3] + '...'
            self.filelabel.config(text=name)
            self.nameFile.set(Path(filename).stem)
            self.useFileButton.state(['!disabled'])
            self.updateLoadPreview()

    def useFile(self):
        filename = self.loadedFile.get()
        if not os.path.isfile(filename):
            MfxMessageDialog(
                self.top, title=_("Import File"),
                text=_("The selected file no longer exists."), bitmap="error")
            return
        tile = Tile()
        scaling = self.fileScaling.get()
        searchDirs = []
        if scaling == 'Stretch':
            tile.stretch = 1
            searchDirs.append(os.path.join("tiles", "stretch"))
        elif scaling == 'Preserve aspect ratio':
            tile.stretch = 1
            tile.save_aspect = 1
            searchDirs.append(os.path.join("tiles", "save-aspect"))
        elif scaling == 'Tile':
            searchDirs.append("tiles-*")
        tile.name = self.nameFile.get()
        extension = Path(filename).suffix
        dirs = self.manager.getSearchDirs(
            self.app, searchDirs, "PYSOL_TILES")
        copySuccess = False
        destPath = ""
        for dirname in dirs:
            try:
                destPath = os.path.join(dirname, (tile.name + extension))
                shutil.copy2(filename, destPath)
                copySuccess = True
                break
            except EnvironmentError:
                pass
        if (not copySuccess):
            MfxMessageDialog(
                self.top, title=_("Import File"),
                text=_("Failed to import file."), bitmap="error")
            return

        tile.filename = destPath

        self.manager.register(tile)

        # Refresh lists so the new tile appears and select it
        self.refreshTreeData()
        self.performSearch()
        try:
            self.tree.updateSelection(tile.index)
            self.updatePreview(tile.index)
            self.speakTileInfo(tile.name)
        except (ValueError, tkinter.TclError):
            pass

    def refreshTreeData(self):
        data = self.TreeDataHolder_Class.data
        if data is None:
            return
        data.all_objects = self.manager.getAllSortedByName()
        data.all_objects = [obj for obj in data.all_objects if not obj.error]
        data.all_objects = [tile for tile in data.all_objects
                            if tile.index > 0 and tile.filename]
        # Clear cached subnodes so they re-fetch
        for node in data.rootnodes:
            if callable(getattr(node, 'select_func', None)) and not isinstance(
                    getattr(node, 'select_func', None), (tuple, list)):
                node.subnodes = None
        self.tree.redraw()

    def advancedSearch(self):
        d = SelectTileAdvancedSearch(self.top, _("Advanced search"),
                                     self.criteria)
        if d.status == 0 and d.button == 0:
            self.criteria = SearchCriteria()
            self.performSearch()

        if d.status == 0 and d.button == 1:
            self.criteria.name = d.name.get()

            self.list_searchtext.delete(0, "end")
            self.list_searchtext.insert(0, d.name.get())

            self.criteria.type = d.type.get()
            self.criteria.size = d.size.get()

            self.performSearch()

    def selectSearchResult(self, event):
        if self.list.size() <= 0:
            return
        oldcur = self.list["cursor"]
        self.list["cursor"] = "watch"
        sel = self.list.get(self.list.curselection())
        cardset = self.manager.getByName(sel).index
        self.list.update_idletasks()
        self.tree.n_selections += 1
        self.tree.updateSelection(cardset)
        self.updatePreview(cardset)
        self.speakTileInfo(sel)
        self.list["cursor"] = oldcur

    def speakTileInfo(self, name):
        self.app.speech.speak(name)

    def updatePreview(self, key, scaling=-1):
        if scaling < 0:
            scaling = self.preview_scaling
        if key == self.preview_key and scaling == self.preview_scaling:
            return
        canvas = self.preview.canvas
        canvas.deleteAllItems()

        self.preview_scaling = scaling
        if isinstance(key, str):
            if USE_PIL:
                self.textScale['state'] = 'disabled'
            # solid color
            canvas.config(bg=key)
            canvas.setTile(None)
            canvas.setTextColor(None)
            self.preview_key = key
            self.table_color = key
        else:
            # image
            tile = self.manager.get(key)
            if tile:
                if USE_PIL:
                    if tile.stretch:
                        self.textScale['state'] = 'readonly'
                    else:
                        self.textScale['state'] = 'disabled'
                if self.preview.setTile(self.app, key, scaling):
                    self.preview_key = key
                    return
            self.preview_key = -1


class SearchCriteria:
    def __init__(self):
        self.name = ""
        self.type = ""
        self.size = ""

        self.sizeOptions = {"": -1,
                            "Tile": TTI.SIZE_TILE,
                            "SD": TTI.SIZE_SD,
                            "HD": TTI.SIZE_HD,
                            "4K": TTI.SIZE_4K}
        self.typeOptions = ("", "Images", "Tiles")


class SelectTileAdvancedSearch(MfxDialog):
    def __init__(self, parent, title, criteria, **kw):
        kw = self.initKw(kw)
        MfxDialog.__init__(self, parent, title, kw.resizable, kw.default)
        top_frame, bottom_frame = self.createFrames(kw)

        self.createBitmaps(top_frame, kw)
        #
        self.name = tkinter.StringVar()
        self.name.set(criteria.name)
        self.type = tkinter.StringVar()
        self.type.set(criteria.type)
        self.size = tkinter.StringVar()
        self.size.set(criteria.size)
        #
        row = 0

        labelName = tkinter.Label(top_frame, text=_("Name:"), anchor="w")
        labelName.grid(row=row, column=0, columnspan=1, sticky='ew',
                       padx=1, pady=1)
        textName = PysolEntry(top_frame, textvariable=self.name,
                              fieldname=_("Name:"))
        textName.grid(row=row, column=1, columnspan=4, sticky='ew',
                      padx=1, pady=1)
        row += 1

        typeValues = list(criteria.typeOptions)

        labelType = tkinter.Label(top_frame, text=_("Type:"), anchor="w")
        labelType.grid(row=row, column=0, columnspan=1, sticky='ew',
                       padx=1, pady=1)
        textType = PysolCombo(top_frame, values=typeValues,
                              fieldname=_("Type:"),
                              textvariable=self.type, state='readonly')
        textType.grid(row=row, column=1, columnspan=4, sticky='ew',
                      padx=1, pady=1)
        row += 1
        if USE_PIL:
            sizeValues = list(criteria.sizeOptions.keys())

            labelSize = tkinter.Label(top_frame, text=_("Size:"), anchor="w")
            labelSize.grid(row=row, column=0, columnspan=1, sticky='ew',
                           padx=1, pady=1)
            textSize = PysolCombo(top_frame, values=sizeValues,
                                  fieldname=_("Size:"),
                                  textvariable=self.size, state='readonly')
            textSize.grid(row=row, column=1, columnspan=4, sticky='ew',
                          padx=1, pady=1)
            row += 1

        top_frame.columnconfigure(4, weight=1)

        focus = self.createButtons(bottom_frame, kw)
        # focus = text_w
        self.mainloop(focus, kw.timeout)

    def initKw(self, kw):
        kw = KwStruct(kw,
                      strings=(_("C&lear"), 'sep', _("&OK"), _("&Cancel")),
                      default=1, padx=10, pady=10,
                      )
        return MfxDialog.initKw(self, kw)
