/* wconfig.cc
 * This file belongs to Worker, a file manager for UN*X/X11.
 * Copyright (C) 2001-2025 Ralf Hoffmann.
 * You can contact me at: ralf@boomerangsworld.de
 *   or http://www.boomerangsworld.de/worker
 *
 * 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 2 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, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "wconfig.h"
#include "worker.h"
#include "filereq.h"
#include "fontreq.h"
#include <string>
#include "pdatei.h"
#include "configheader.h"
#include "aguix/acontainer.h"
#include "aguix/acontainerbb.h"
#include "aguix/kartei.h"
#include "condparser.h"
#include "ownop.h"
#include "aguix/slider.h"
#include "panel.hh"
#include "wconfig_lang.hh"
#include "wconfig_palette.hh"
#include "wconfig_font.hh"
#include "wconfig_start.hh"
#include "wconfig_mouse.hh"
#include "wconfig_clock.hh"
#include "wconfig_lister.hh"
#include "wconfig_listview.hh"
#include "wconfig_time.hh"
#include "wconfig_color.hh"
#include "wconfig_hotkey.hh"
#include "wconfig_filetype.hh"
#include "wconfig_path.hh"
#include "wconfig_button.hh"
#include "wconfig_dcd.hh"
#include "wconfig_pathjump_allow.hh"
#include "wconfig_colorconf.hh"
#include "wconfig_buttongrpconf.hh"
#include "wconfig_cachesize.hh"
#include "wconfig_ownerconf.hh"
#include "wconfig_termconf.hh"
#include "wconfig_dirsizeconf.hh"
#include "wconfig_layout.hh"
#include "wconfig_imexport.hh"
#include "wconfig_mainui.hh"
#include "wconfig_expertui.hh"
#include "wconfig_bookmarkcolor.hh"
#include "wconfig_directory_presets.hh"
#include "wc_color.hh"
#include "wcdoubleshortkey.hh"
#include "wcpath.hh"
#include "wcfiletype.hh"
#include "wchotkey.hh"
#include "wcbutton.hh"
#include "workerversion.h"
#include "wconfig_generalconf.hh"
#include <set>
#include <algorithm>
#include "magic_db.hh"
#include "wconfig_volman.hh"
#include "workerinitialsettings.hh"
#include "nwc_path.hh"
#include "worker_locale.h"
#include "aguix/button.h"
#include "aguix/bevelbox.h"
#include "aguix/solidbutton.h"
#include "aguix/fieldlistview.h"
#include "aguix/stringgadget.h"
#include "aguix/choosebutton.h"
#include "aguix/cyclebutton.h"
#include "simplelist.hh"
#include "datei.h"
#include "flattypelist.hh"
#include "fileentry.hh"
#include "aguix/utf8.hh"
#include "stringmatcher_flexiblematch.hh"
#include "worker_commands.h"
#include "flagreplacer.hh"
#include "wconfig_kvppanel.hh"

#define DEFAULT_TIME_STRING "%H:%M:%S"
#define DEFAULT_DATE_STRING "%d %b %Y"

static const char * predefined_dates[] = { "%d %b %Y",
                                           "%m/%d/%y",
                                           "%d.%m.%Y" };
static const char * predefined_times[] = { "%H:%M:%S",
                                           "%H:%M" };

#define DEFAULT_X11_FONT_FIXED "fixed"
#define DEFAULT_XFT_FONT_FIXED "Mono-10"
#define DEFAULT_XFT_FONT_VARIABLE "Sans-10"

WConfig *wconfig;
WConfig *lconfig;

bool WConfig::always_keep_old_key = false;

/*
 * configures the filetypes
 *
 * args:
 *   bool allowRemoveUnique
 *     when true allow to remove the unique types (dir, notyet,...)
 *     mainly used for export
 *
 * returnvalues:
 *   bool:  true when okay was choosen
 *          false otherwise
 */
bool WConfig::changeTypes( bool allowRemoveUnique )
{
  WConfig *twconfig = duplicate();
  AGUIX *aguix = worker->getAGUIX();
  std::string s1;
  WCFiletype *cutft;

  AWindow *win = new AWindow( aguix, 10, 10, 10, 10, catalog.getLocale( 6 ), AWindow::AWINDOW_DIALOG );
  win->create();
  
  AContainer *ac1 = win->setContainer( new AContainer( win, 1, 2 ), true );
  ac1->setMinSpace( 5 );
  ac1->setMaxSpace( 5 );
  
  FiletypePanel *ftp = new FiletypePanel( *win, *this );
  ftp->create();
  ftp->show();
  ftp->setAllowRemoveUnique( true );
  int w = ftp->getWidth();
  int h = ftp->getHeight();
  
  ac1->add( ftp, 0, 0, AContainer::CO_MIN );
  ac1->setMinWidth( w, 0, 0 );
  ac1->setMinHeight( h, 0, 0 );
  win->contMaximize( false );
  
  AContainer *ac1_2 = ac1->add( new AContainer( win, 2, 1 ), 0, 1 );
  ac1_2->setMinSpace( 5 );
  ac1_2->setMaxSpace( -1 );
  ac1_2->setBorderWidth( 0 );
  Button *okb = (Button*)ac1_2->add( new Button( aguix,
                                                 0,
                                                 0,
                                                 catalog.getLocale( 11 ),
                                                 0 ),
                                     0, 0, AContainer::CO_INCW );
  Button *cancelb = (Button*)ac1_2->add( new Button( aguix,
                                                     0,
                                                     0,
                                                     catalog.getLocale( 8 ),
                                                     0 ),
                                         1, 0, AContainer::CO_INCW );
  win->setDoTabCycling( true );
  win->contMaximize( true );
  win->show();
                                       
  AGMessage *msg;
  while ( ( msg = aguix->GetMessage( NULL ) ) != NULL ) aguix->ReplyMessage( msg );
  int ende = 0;

  cutft = NULL;

  while ( ende == 0 ) {
    msg = aguix->WaitMessage( win );
    if ( msg != NULL ) {
      if ( msg->type == AG_CLOSEWINDOW ) {
        if ( msg->closewindow.window == win->getWindow() ) ende = -1;
      } else if ( msg->type == AG_BUTTONCLICKED ) {
        if ( msg->button.button == okb ) ende = 1;
        else if ( msg->button.button == cancelb ) ende = -1;
      }
      aguix->ReplyMessage( msg );
    }
  }
  ftp->saveValues();
  if ( ende == -1 ) {
    // Wiederherstellen
    setFiletypes( twconfig->getFiletypes() );
    setDontCheckDirs( twconfig->getDontCheckDirs() );
    setDontCheckVirtual( twconfig->getDontCheckVirtual() );
  }
  delete win;
  delete twconfig;
  if ( cutft != NULL ) delete cutft;
  return ( ende == -1 ) ? false : true;
}

bool WConfig::changeHotkeys()
{
  WConfig *twconfig=duplicate();
  AGUIX *aguix=worker->getAGUIX();

  AWindow *win = new AWindow( aguix, 10, 10, 10, 10, catalog.getLocale( 91 ), AWindow::AWINDOW_DIALOG );
  win->create();

  AContainer *ac1 = win->setContainer( new AContainer( win, 1, 2 ), true );
  ac1->setMinSpace( 5 );
  ac1->setMaxSpace( 5 );

  HotkeyPanel *hp = new HotkeyPanel( *win, *this );
  hp->create();
  hp->show();
  int w = hp->getWidth();
  int h = hp->getHeight();
  
  ac1->add( hp, 0, 0, AContainer::CO_MIN );
  ac1->setMinWidth( w, 0, 0 );
  ac1->setMinHeight( h, 0, 0 );
  win->contMaximize( false );
  
  AContainer *ac1_2 = ac1->add( new AContainer( win, 2, 1 ), 0, 1 );
  ac1_2->setMinSpace( 5 );
  ac1_2->setMaxSpace( -1 );
  ac1_2->setBorderWidth( 0 );
  Button *okb = (Button*)ac1_2->add( new Button( aguix,
                                                 0,
                                                 0,
                                                 catalog.getLocale( 11 ),
                                                 0 ),
                                     0, 0, AContainer::CO_INCW );
  Button *cancelb = (Button*)ac1_2->add( new Button( aguix,
                                                     0,
                                                     0,
                                                     catalog.getLocale( 8 ),
                                                     0 ),
                                         1, 0, AContainer::CO_INCW );
  win->setDoTabCycling( true );
  win->contMaximize( true );
  win->show();

  AGMessage *msg;
  while((msg=aguix->GetMessage(NULL))!=NULL) aguix->ReplyMessage(msg);
  int ende=0;
  while(ende==0) {
    msg=aguix->WaitMessage(win);
    if(msg!=NULL) {
      if(msg->type==AG_CLOSEWINDOW) {
        if(msg->closewindow.window==win->getWindow()) ende=-1;
      } else if(msg->type==AG_BUTTONCLICKED) {
        if(msg->button.button==okb) ende=1;
        else if(msg->button.button==cancelb) ende=-1;
      }
      aguix->ReplyMessage(msg);
    }
  }
  hp->saveValues();
  if(ende==-1) {
    // Wiederherstellen
    setHotkeys(twconfig->getHotkeys());
    // also restore buttons and paths (for the case the user entered a shortkey from one of this
    setButtons(twconfig->getButtons());
    setPaths(twconfig->getPaths());
  }
  delete win;
  delete twconfig;
  return (ende==-1)?false:true;
}

bool WConfig::changeButtons()
{
  WConfig *twconfig=duplicate();
  AGUIX *aguix=worker->getAGUIX();
  
  AWindow *win = new AWindow( aguix, 10, 10, 10, 10, catalog.getLocale( 4 ), AWindow::AWINDOW_DIALOG );
  win->create();

  AContainer *ac1 = win->setContainer( new AContainer( win, 1, 2 ), true );
  ac1->setMinSpace( 5 );
  ac1->setMaxSpace( 5 );

  ButtonPanel *bp = new ButtonPanel( *win, *this );
  bp->create();
  bp->show();
  int w = bp->getWidth();
  int h = bp->getHeight();
  
  ac1->add( bp, 0, 0, AContainer::CO_MIN );
  ac1->setMinWidth( w, 0, 0 );
  ac1->setMinHeight( h, 0, 0 );
  win->contMaximize( false );
  
  AContainer *ac1_2 = ac1->add( new AContainer( win, 2, 1 ), 0, 1 );
  ac1_2->setMinSpace( 5 );
  ac1_2->setMaxSpace( -1 );
  ac1_2->setBorderWidth( 0 );
  Button *okb = (Button*)ac1_2->add( new Button( aguix,
                                                 0,
                                                 0,
                                                 catalog.getLocale( 11 ),
                                                 0 ),
                                     0, 0, AContainer::CO_INCW );
  Button *cancelb = (Button*)ac1_2->add( new Button( aguix,
                                                     0,
                                                     0,
                                                     catalog.getLocale( 8 ),
                                                     0 ),
                                         1, 0, AContainer::CO_INCW );
  win->setDoTabCycling( true );
  win->contMaximize( true );
  win->show();
  AGMessage *msg;
  while((msg=aguix->GetMessage(NULL))!=NULL) aguix->ReplyMessage(msg);
  int ende=0;
  while(ende==0) {
    msg=aguix->WaitMessage(win);
    if(msg!=NULL) {
      if(msg->type==AG_CLOSEWINDOW) {
        if(msg->closewindow.window==win->getWindow()) ende=-1;
      } else if(msg->type==AG_BUTTONCLICKED) {
        if(msg->button.button==okb) ende=1;
        else if(msg->button.button==cancelb) ende=-1;
      }
      aguix->ReplyMessage(msg);
    }
  }
  bp->saveValues();
  if(ende==-1) {
    // Wiederherstellen
    setButtons(twconfig->getButtons());
    // also restore paths and hotkeys (for the case the user entered a shortkey from one of this
    setPaths(twconfig->getPaths());
    setHotkeys(twconfig->getHotkeys());
  } else cleanUpButtons();
  delete win;
  delete twconfig;
  return (ende==-1)?false:true;
}

int WConfig::palette()
{
  return palette(-1);
}

int WConfig::palette(int startcol)
{
  AGUIX *aguix=worker->getAGUIX();
  int w,h;
  w=5+256+10+5;
  h=5+256+10+5+aguix->getCharHeight()+4+5;
  AWindow *win = new AWindow( aguix, 10, 10, w, h, catalog.getLocale( 45 ), AWindow::AWINDOW_DIALOG );
  win->create();
  int sx = (int)sqrt( (double)( colors->size() ) );
  if((sx*sx)<colors->size()) sx++;
  int th=256/sx;
  for(int i=0;i<colors->size();i++) {
    win->add(new Button(aguix,
                        10+(i%sx)*th,
                        10+(i/sx)*th,
                        th,
                        th,
                        "",
                        0,
                        i,
                        i+1));
  }
  ((BevelBox*)win->add(new BevelBox(aguix,
                                    5,
                                    5,
                                    256+10,
                                    256+10,
                                    1)))->toBack();
  int t1 = aguix->getTextWidth( catalog.getLocale( 11 ) ) + 10;
  int t2 = aguix->getTextWidth( catalog.getLocale( 8 ) ) + 10;
  Button *okb=(Button*)win->add(new Button(aguix,
                                           5,
                                           256+20,
                                           t1,
                                           catalog.getLocale(11),
                                           0));
  Button *cancelb=(Button*)win->add(new Button(aguix,
                                               w-5-t2,
                                               256+20,
                                               t2,
                                               catalog.getLocale(8),
                                               0));  
  SolidButton *editcolsb=(SolidButton*)win->add(new SolidButton(aguix,
                                                5+t1+5,
                                                256+20,
                                                w-5-5-10-t1-t2,
                                                "",
                                                0,
                                                (startcol>=0)?startcol:0,
                                                false));
  win->setDoTabCycling( true );
  win->resize(w,h);
  win->setMaxSize(w,h);
  win->setMinSize(w,h);
  win->show();
  AGMessage *msg;
  while((msg=aguix->GetMessage(NULL))!=NULL) aguix->ReplyMessage(msg);
  int ende=0,selcol=(startcol>=0)?startcol:-1;
  while(ende==0) {
    msg=aguix->WaitMessage(win);
    if(msg!=NULL) {
      if(msg->type==AG_CLOSEWINDOW) {
        if(msg->closewindow.window==win->getWindow()) ende=-1;
      } else if(msg->type==AG_BUTTONCLICKED) {
        if(msg->button.button==okb) ende=1;
        else if(msg->button.button==cancelb) ende=-1;
        else if(msg->button.button->getData()>0) {
          // ein Eintrag wurde ausgewaehlt
          selcol=msg->button.button->getData()-1;
          editcolsb->setBG(selcol);
        }
      } else if ( msg->type == AG_KEYPRESSED ) {
          if ( win->isParent( msg->key.window, false ) == true ) {
              switch ( msg->key.key ) {
                  case XK_Escape:
                      ende = -1;
                      break;
              }
          }
      }
      aguix->ReplyMessage(msg);
    }
  }
  delete win;
  return (ende==-1)?-1:selcol;
}

void WConfig::applyColorList(List *cols)
{
    AGUIX *aguix = worker->getAGUIX();
    
    aguix->freeColors();
    
    int id = cols->initEnum();
    WC_Color *tc1 = (WC_Color*)cols->getFirstElement();
    while ( tc1 != NULL ) {
        if ( aguix->AddColor( tc1->getRed(), tc1->getGreen(), tc1->getBlue() ).getColor() < 0 ) {
            fprintf( stderr, "Worker: Can't allocate color %d,%d,%d!\n", tc1->getRed(), tc1->getGreen(), tc1->getBlue() );
        }
        tc1 = (WC_Color*)cols->getNextElement();
    }
    cols->closeEnum( id );
}

void WConfig::setLang( const char *nlang )
{
  if(lang!=NULL) _freesafe(lang);
  if(nlang==NULL) lang=dupstring("builtin");
  else lang=dupstring(nlang);
}

void WConfig::setTerminalBin(const char *ntb)
{
  if(isCorrectTerminalBin(ntb)==true) {
    if(terminalbin!=NULL) _freesafe(terminalbin);
    if(ntb==NULL) terminalbin=dupstring(TERMINAL_BIN);
    else terminalbin=dupstring(ntb);
  }
}

void WConfig::setRows(unsigned int nrows)
{
  if((nrows<1)||(nrows>10)) return;
  rows=nrows;
  cleanUpPaths();
  cleanUpButtons();
}

void WConfig::setColumns(unsigned int ncols)
{
  if((ncols<1)||(ncols>20)) return;
  columns=ncols;
  cleanUpPaths();
  cleanUpButtons();
}

void WConfig::setCacheSize(unsigned int ncs)
{
  if(ncs<1) return;
  cachesize=ncs;
}

void WConfig::setHBarTop(int index2,bool val)
{
  if((index2<0)||(index2>1)) return;
  hbar_top[index2]=val;
}

void WConfig::setVBarLeft(int index2,bool val)
{
  if((index2<0)||(index2>1)) return;
  vbar_left[index2]=val;
}

void WConfig::setHBarHeight(int index2,unsigned int nh)
{
  if((index2<0)||(index2>1)) return;
  if(nh<5) return;
  hbar_height[index2]=nh;
}

void WConfig::setVBarWidth(int index2,unsigned int nw)
{
  if((index2<0)||(index2>1)) return;
  if(nw<5) return;
  vbar_width[index2]=nw;
}

void WConfig::setVisCols( int side, const std::vector<WorkerTypes::listcol_t> *nv )
{
  if ( ( side < 0 ) || ( side > 1 ) ) return;
  if ( nv == NULL ) return;
  
  viscols[side] = *nv;
}

char *WConfig::getLang()
{
  return lang;
}

char *WConfig::getTerminalBin()
{
  return terminalbin;
}

unsigned int WConfig::getRows()
{
  return rows;
}

unsigned int WConfig::getColumns()
{
  return columns;
}

unsigned int WConfig::getCacheSize()
{
  return cachesize;
}

bool WConfig::getHBarTop(int index2)
{
  if((index2<0)||(index2>1)) return false;
  return hbar_top[index2];
}

bool WConfig::getVBarLeft(int index2)
{
  if((index2<0)||(index2>1)) return false;
  return vbar_left[index2];
}

unsigned int WConfig::getHBarHeight(int index2)
{
  if((index2<0)||(index2>1)) return 10;
  return hbar_height[index2];
}

unsigned int WConfig::getVBarWidth(int index2)
{
  if((index2<0)||(index2>1)) return 10;
  return vbar_width[index2];
}

const std::vector<WorkerTypes::listcol_t> *WConfig::getVisCols( int side ) const
{
  return &( viscols[ ( side == 1 ) ? 1 : 0 ] );
}

void WConfig::clearVisCols( int side )
{
  if ( ( side < 0 ) || ( side > 1 ) ) return;
  
  viscols[side].clear();
}

void WConfig::addListCol( int side, WorkerTypes::listcol_t nv )
{
  unsigned int ui;
  bool found = false;

  if ( ( side < 0 ) || ( side > 1 ) ) return;

  for ( ui = 0; ui < viscols[side].size(); ui++ ) {
    if ( viscols[side][ui] == nv ) {
      found = true;
      break;
    }
  }
  if ( found == false ) {
    viscols[side].push_back( nv );
  }
}

void WConfig::setStartDir(int index2,const char *ndir)
{
  if((index2<0)||(index2>1)) return;
  if(dir[index2]!=NULL) _freesafe(dir[index2]);
  if(ndir==NULL) dir[index2]=dupstring("");
  else dir[index2]=dupstring(ndir);
}

char *WConfig::getStartDir(int index2)
{
  if((index2<0)||(index2>1)) return NULL;
  return dir[index2];
}

void WConfig::setFont(int index2,const char *nfont)
{
  if ( index2 < 0 || index2 > 6 ) return;

  std::string font;

  if ( nfont != NULL ) font = nfont;

  // now set the corresponding entry in font_names
  font_type_t f_id = FONT_X11_GLOBAL;
  switch ( index2 ) {
      case 1:
#ifdef HAVE_XFT
          f_id = FONT_XFT_BUTTONS;
#else
          f_id = FONT_X11_BUTTONS;
#endif
          break;
      case 2:
#ifdef HAVE_XFT
          f_id = FONT_XFT_LEFT;
#else
          f_id = FONT_X11_LEFT;
#endif
          break;
      case 3:
#ifdef HAVE_XFT
          f_id = FONT_XFT_RIGHT;
#else
          f_id = FONT_X11_RIGHT;
#endif
          break;
      case 4:
#ifdef HAVE_XFT
          f_id = FONT_XFT_TEXTVIEW;
#else
          f_id = FONT_X11_TEXTVIEW;
#endif
          break;
      case 5:
#ifdef HAVE_XFT
          f_id = FONT_XFT_STATEBAR;
#else
          f_id = FONT_X11_STATEBAR;
#endif
          break;
      case 6:
#ifdef HAVE_XFT
          f_id = FONT_XFT_TEXTVIEW_ALT;
#else
          f_id = FONT_X11_TEXTVIEW_ALT;
#endif
          break;
      default:
#ifdef HAVE_XFT
          f_id = FONT_XFT_GLOBAL;
#else
          f_id = FONT_X11_GLOBAL;
#endif
          break;
  }
  setFontName( f_id, font );
}

std::string WConfig::getFont( int index2 )
{
    if ( index2 < 0 || index2 > 6 ) return NULL;

    font_type_t f_id = FONT_X11_GLOBAL;
    switch ( index2 ) {
        case 1:
#ifdef HAVE_XFT
            f_id = FONT_XFT_BUTTONS;
#else
            f_id = FONT_X11_BUTTONS;
#endif
            break;
        case 2:
#ifdef HAVE_XFT
            f_id = FONT_XFT_LEFT;
#else
            f_id = FONT_X11_LEFT;
#endif
            break;
        case 3:
#ifdef HAVE_XFT
            f_id = FONT_XFT_RIGHT;
#else
            f_id = FONT_X11_RIGHT;
#endif
            break;
        case 4:
#ifdef HAVE_XFT
            f_id = FONT_XFT_TEXTVIEW;
#else
            f_id = FONT_X11_TEXTVIEW;
#endif
            break;
        case 5:
#ifdef HAVE_XFT
            f_id = FONT_XFT_STATEBAR;
#else
            f_id = FONT_X11_STATEBAR;
#endif
            break;
        case 6:
#ifdef HAVE_XFT
            f_id = FONT_XFT_TEXTVIEW_ALT;
#else
            f_id = FONT_X11_TEXTVIEW_ALT;
#endif
            break;
        default:
#ifdef HAVE_XFT
            f_id = FONT_XFT_GLOBAL;
#else
            f_id = FONT_X11_GLOBAL;
#endif
            break;
    }
    return getFontName( f_id );
}

void WConfig::setPaths(List *npaths)
{
  WCPath *tp;
  int id=paths->initEnum();
  tp=(WCPath*)paths->getFirstElement(id);
  while(tp!=NULL) {
    delete tp;
    tp=(WCPath*)paths->getNextElement(id);
  }
  paths->closeEnum(id);
  paths->removeAllElements();
  id=npaths->initEnum();
  tp=(WCPath*)npaths->getFirstElement(id);
  while(tp!=NULL) {
    paths->addElement(tp->duplicate());
    tp=(WCPath*)npaths->getNextElement(id);
  }
  npaths->closeEnum(id);
  cleanUpPaths();
}

List *WConfig::getPaths()
{
  return paths;
}

void WConfig::setFiletypes(List *nfts)
{
  WCFiletype *tft;
  int id=filetypes->initEnum();
  tft=(WCFiletype*)filetypes->getFirstElement(id);
  while(tft!=NULL) {
    delete tft;
    tft=(WCFiletype*)filetypes->getNextElement(id);
  }
  filetypes->closeEnum(id);
  filetypes->removeAllElements();
  id=nfts->initEnum();
  tft=(WCFiletype*)nfts->getFirstElement(id);
  while(tft!=NULL) {
    filetypes->addElement(tft->duplicate());
    tft=(WCFiletype*)nfts->getNextElement(id);
  }
  nfts->closeEnum(id);
  
  /* clear special type pointers for fast lookup
   * I could do initFixTypes
   * but this is not so good for importing because
   * there would be always the fixtypes
   * this method should just take the list and not more
   * all this initFixType-stuff is for worker and not needed
   * in configuration
   * but (TODO) it's better code when this pointers are always
   * correct */
  notyettype = NULL;
  unknowntype = NULL;
  dirtype = NULL;
  voidtype = NULL;
}

List *WConfig::getFiletypes()
{
  return filetypes;
}

void WConfig::setHotkeys(List *nhks)
{
  WCHotkey *thk;
  int id=hotkeys->initEnum();
  thk=(WCHotkey*)hotkeys->getFirstElement(id);
  while(thk!=NULL) {
    delete thk;
    thk=(WCHotkey*)hotkeys->getNextElement(id);
  }
  hotkeys->closeEnum(id);
  hotkeys->removeAllElements();
  id=nhks->initEnum();
  thk=(WCHotkey*)nhks->getFirstElement(id);
  while(thk!=NULL) {
    hotkeys->addElement(thk->duplicate());
    thk=(WCHotkey*)nhks->getNextElement(id);
  }
  nhks->closeEnum(id);
}

List *WConfig::getHotkeys()
{
  return hotkeys;
}

void WConfig::setButtons(List *nbs)
{
  WCButton *tb;
  int id=buttons->initEnum();
  tb=(WCButton*)buttons->getFirstElement(id);
  while(tb!=NULL) {
    delete tb;
    tb=(WCButton*)buttons->getNextElement(id);
  }
  buttons->closeEnum(id);
  buttons->removeAllElements();
  id=nbs->initEnum();
  tb=(WCButton*)nbs->getFirstElement(id);
  while(tb!=NULL) {
    buttons->addElement(tb->duplicate());
    tb=(WCButton*)nbs->getNextElement(id);
  }
  nbs->closeEnum(id);
  cleanUpButtons();
}

List *WConfig::getButtons()
{
  return buttons;
}

void WConfig::cleanUpPaths()
{
  int id=paths->initEnum();
  WCPath *tp=(WCPath*)paths->getLastElement(id);
  while(tp!=NULL) {
    // Alle leeren am Ende entfernen
    if(tp->getCheck()==false) {
      delete tp;
      paths->removeLastElement();
    } else break;
    tp=(WCPath*)paths->getLastElement(id);
  }
  // Und nun noch auf Bankgroesse auffuellen
  paths->closeEnum(id);
  while((((paths->size())%rows)!=0)||(paths->size()==0)) {
    paths->addElement(new WCPath());
  }
}

void WConfig::cleanUpButtons()
{
  int banksize=rows*columns*2;
  int id=buttons->initEnum();
  WCButton *tb=(WCButton*)buttons->getLastElement(id);
  while(tb!=NULL) {
    // Alle leeren am Ende entfernen
    if(tb->getCheck()==false) {
      delete tb;
      buttons->removeLastElement();
    } else break;
    tb=(WCButton*)buttons->getLastElement(id);
  }
  // Und nun noch auf Bankgroesse auffuellen
  buttons->closeEnum(id);
  while((((buttons->size())%banksize)!=0)||(buttons->size()==0)) {
    buttons->addElement(new WCButton());
  }
}

WConfig::WConfig(Worker *tworker)
{
  unsigned int i;
  this->worker=tworker;
  lang=dupstring("");
  terminalbin=dupstring(TERMINAL_BIN);
  rows=1;
  columns=1;
  cachesize=10;
  colors=new List();
  colors->addElement(new WC_Color(160,160,160));
  colors->addElement(new WC_Color(0,0,0));
  colors->addElement(new WC_Color(255,255,255));
  colors->addElement(new WC_Color(0,85,187));
  colors->addElement(new WC_Color(204,34,0));
  colors->addElement(new WC_Color(50,180,20));
  colors->addElement(new WC_Color(119,0,119));
  colors->addElement(new WC_Color(238,170,68));
  hbar_top[0]=false;
  hbar_top[1]=false;
  vbar_left[0]=false;
  vbar_left[1]=true;
  hbar_height[0]=10;
  hbar_height[1]=10;
  vbar_width[0]=10;
  vbar_width[1]=10;
  for ( i = 0; i < 2; i++ ) {
    viscols[i].push_back( WorkerTypes::LISTCOL_PERM );
    viscols[i].push_back( WorkerTypes::LISTCOL_SIZE );
    viscols[i].push_back( WorkerTypes::LISTCOL_NAME );
    viscols[i].push_back( WorkerTypes::LISTCOL_TYPE );
  }
  showHeader[0] = true;
  showHeader[1] = true;
  dir[0]=dupstring("");
  dir[1]=dupstring("");

  m_path_entry_on_top[0] = false;
  m_path_entry_on_top[1] = false;

  setFontName( FONT_X11_GLOBAL, DEFAULT_X11_FONT_FIXED );
  setFontName( FONT_X11_BUTTONS, DEFAULT_X11_FONT_FIXED );
  setFontName( FONT_X11_LEFT, DEFAULT_X11_FONT_FIXED );
  setFontName( FONT_X11_RIGHT, DEFAULT_X11_FONT_FIXED );
  setFontName( FONT_X11_TEXTVIEW, DEFAULT_X11_FONT_FIXED );
  setFontName( FONT_X11_STATEBAR, DEFAULT_X11_FONT_FIXED );
  setFontName( FONT_X11_TEXTVIEW_ALT, DEFAULT_X11_FONT_FIXED );
  setFontName( FONT_XFT_GLOBAL, DEFAULT_XFT_FONT_VARIABLE );
  setFontName( FONT_XFT_BUTTONS, DEFAULT_XFT_FONT_VARIABLE );
  setFontName( FONT_XFT_LEFT, DEFAULT_XFT_FONT_VARIABLE );
  setFontName( FONT_XFT_RIGHT, DEFAULT_XFT_FONT_VARIABLE );
  setFontName( FONT_XFT_TEXTVIEW, DEFAULT_XFT_FONT_VARIABLE );
  setFontName( FONT_XFT_STATEBAR, DEFAULT_XFT_FONT_VARIABLE );
  setFontName( FONT_XFT_TEXTVIEW_ALT, DEFAULT_XFT_FONT_FIXED );

  paths=new List();
  for(i=0;i<rows;i++) {
    paths->addElement(new WCPath());
  }
  filetypes=new List();
  hotkeys=new List();
  buttons=new List();
  for(i=0;i<(rows*columns);i++) {
    buttons->addElement(new WCButton());
    buttons->addElement(new WCButton());
  }
  notyettype=NULL;
  dirtype=NULL;
  voidtype = NULL;
  unknowntype = NULL;
  initFixTypes();
  ownerstringtype=0;

  clockbar_mode=CLOCKBAR_MODE_TIMERAM;
  clockbar_updatetime=1;
  m_clockbar_hints = true;

  dontcheckvirtual = true;
  
  showStringForDirSize=false;
  stringForDirSize=dupstring("<DIR>");
  stringForDirSizeLen=strlen(stringForDirSize);
  
  setDateFormat( 0 );
  date_formatstring = dupstring( "" );
  setDateFormatString( NULL );
  setDateSubst( true );
  
  setTimeFormat( 0 );
  time_formatstring = dupstring( "" );
  setTimeFormatString( NULL );
  
  setDateBeforeTime( false );

  m_layout_conf.setButtonVert( false );
  m_layout_conf.setListViewVert( false );
  m_layout_conf.setListViewWeight( 5 );
  m_layout_conf.setWeightRelToActive( false );

  mouseConf.select_button = 1;
  mouseConf.activate_button = 2;
  mouseConf.scroll_button = 3;
  mouseConf.context_button = 3;
  mouseConf.activate_mod = 0;
  mouseConf.scroll_mod = ShiftMask;
  mouseConf.context_mod = 0;
  mouseConf.select_method = MOUSECONF_NORMAL_MODE;
  mouseConf.context_menu_with_delayed_activate = false;

  setDefaultConfig();
  
  configureButtonSize[0] = -1;
  configureButtonSize[1] = -1;
  changeTypesSize[0] = -1;
  changeTypesSize[1] = -1;
  changeHotkeysSize[0] = -1;
  changeHotkeysSize[1] = -1;
  configureFiletypeSize[0] = -1;
  configureFiletypeSize[1] = -1;
  configureHotkeySize[0] = -1;
  configureHotkeySize[1] = -1;
  lastRequestCommand = NULL;

  currentConfigTime = 0;

  always_keep_old_key = false;

  m_save_worker_state_on_exit = true;

  m_vm_settings.request_action = true;
  m_vm_settings.preferred_udisks_version = 1;

  m_use_string_compare_mode = StringComparator::STRING_COMPARE_VERSION;

  m_apply_window_dialog_type = true;

  m_use_extended_regex = false;

  m_pathjump_store_files_always = false;

  m_loaded_major_version = 0;
  m_loaded_minor_version = 0;
  m_loaded_patch_version = 0;

  m_restore_tabs_mode = RESTORE_TABS_NEVER;
  m_store_tabs_mode = STORE_TABS_NEVER;

  m_terminal_returns_early = false;

  m_kvp_pool = std::make_shared< WConfigKVPPool >();
}

WConfig::~WConfig()
{
  if(lang!=NULL) _freesafe(lang);
  if(terminalbin!=NULL) _freesafe(terminalbin);
  int id=colors->initEnum();
  WC_Color *tcol=(WC_Color*)colors->getFirstElement(id);
  while(tcol!=NULL) {
    delete tcol;
    tcol=(WC_Color*)colors->getNextElement(id);
  }
  colors->closeEnum(id);
  delete colors;
  if(dir[0]!=NULL) _freesafe(dir[0]);
  if(dir[1]!=NULL) _freesafe(dir[1]);
  id=paths->initEnum();
  WCPath *tp=(WCPath*)paths->getFirstElement(id);
  while(tp!=NULL) {
    delete tp;
    tp=(WCPath*)paths->getNextElement(id);
  }
  paths->closeEnum(id);
  delete paths;
  id=filetypes->initEnum();
  WCFiletype *tft=(WCFiletype*)filetypes->getFirstElement(id);
  while(tft!=NULL) {
    delete tft;
    tft=(WCFiletype*)filetypes->getNextElement(id);
  }
  filetypes->closeEnum(id);
  delete filetypes;
  id=hotkeys->initEnum();
  WCHotkey *thk=(WCHotkey*)hotkeys->getFirstElement(id);
  while(thk!=NULL) {
    delete thk;
    thk=(WCHotkey*)hotkeys->getNextElement(id);
  }
  hotkeys->closeEnum(id);
  delete hotkeys;
  id=buttons->initEnum();
  WCButton *tb=(WCButton*)buttons->getFirstElement(id);
  while(tb!=NULL) {
    delete tb;
    tb=(WCButton*)buttons->getNextElement(id);
  }
  buttons->closeEnum(id);
  delete buttons;

  _freesafe(stringForDirSize);
  
  _freesafe( date_formatstring );
  _freesafe( time_formatstring );
  if ( lastRequestCommand != NULL ) _freesafe( lastRequestCommand );
}

WConfig *WConfig::duplicate()
{
  WConfig *twc=new WConfig(worker);
  twc->setLang(lang);
  twc->setTerminalBin(terminalbin);
  twc->setRows(rows);
  twc->setColumns(columns);
  twc->setCacheSize(cachesize);
  twc->setHBarTop(0,hbar_top[0]);
  twc->setHBarTop(1,hbar_top[1]);
  twc->setVBarLeft(0,vbar_left[0]);
  twc->setVBarLeft(1,vbar_left[1]);
  twc->setHBarHeight(0,hbar_height[0]);
  twc->setHBarHeight(1,hbar_height[1]);
  twc->setVBarWidth(0,vbar_width[0]);
  twc->setVBarWidth(1,vbar_width[1]);
  twc->setVisCols( 0, &viscols[0] );
  twc->setVisCols( 1, &viscols[1] );
  twc->setStartDir(0,dir[0]);
  twc->setStartDir(1,dir[1]);
  twc->setFontNames( m_font_names );
  twc->setPaths(paths);
  twc->setFiletypes(filetypes);
  twc->setHotkeys(hotkeys);
  twc->setButtons(buttons);
  twc->setColors(colors);
  twc->setOwnerstringtype(ownerstringtype);
  twc->setClockbarMode(clockbar_mode);
  twc->setClockbarUpdatetime(clockbar_updatetime);
  twc->setClockbarCommand(clockbar_command);
  twc->setClockbarCustom( m_clockbar_custom[0], 0 );
  twc->setClockbarCustom( m_clockbar_custom[1], 1 );
  twc->setClockbarHints( m_clockbar_hints );
  twc->setDontCheckDirs( m_dont_check_dirs );
  twc->setDontCheckVirtual( dontcheckvirtual );
  twc->setShowStringForDirSize(showStringForDirSize);
  twc->setStringForDirSize(stringForDirSize);
  
  twc->setDateFormat( date_format );
  twc->setDateFormatString( date_formatstring );
  twc->setDateSubst( date_subst );
  twc->setTimeFormat( time_format );
  twc->setTimeFormatString( time_formatstring );
  twc->setDateBeforeTime( date_before_time );
  
  twc->setShowHeader( 0, showHeader[0] );
  twc->setShowHeader( 1, showHeader[1] );
  
  twc->setPathEntryOnTop( 0, getPathEntryOnTop( 0 ) );
  twc->setPathEntryOnTop( 1, getPathEntryOnTop( 1 ) );
  
  twc->setLayoutOrders( getLayoutOrders() );
  twc->setLayoutButtonVert( getLayoutButtonVert() );
  twc->setLayoutListviewVert( getLayoutListviewVert() );
  twc->setLayoutListViewWeight( getLayoutListViewWeight() );
  twc->setLayoutWeightRelToActive( getLayoutWeightRelToActive() );

  twc->setMouseSelectButton( getMouseSelectButton() );
  twc->setMouseActivateButton( getMouseActivateButton() );
  twc->setMouseScrollButton( getMouseScrollButton() );
  twc->setMouseContextButton( getMouseContextButton() );
  twc->setMouseActivateMod( getMouseActivateMod() );
  twc->setMouseScrollMod( getMouseScrollMod() );
  twc->setMouseContextMod( getMouseContextMod() );
  twc->setMouseSelectMethod( getMouseSelectMethod() );
  twc->setMouseContextMenuWithDelayedActivate( getMouseContextMenuWithDelayedActivate() );

  twc->setColorDefs( getColorDefs() );

  twc->setSaveWorkerStateOnExit( getSaveWorkerStateOnExit() );

  twc->setVMMountCommand( getVMMountCommand() );
  twc->setVMUnmountCommand( getVMUnmountCommand() );
  twc->setVMFStabFile( getVMFStabFile() );
  twc->setVMMtabFile( getVMMtabFile() );
  twc->setVMPartitionFile( getVMPartitionFile() );
  twc->setVMRequestAction( getVMRequestAction() );
  twc->setVMEjectCommand( getVMEjectCommand() );
  twc->setVMCloseTrayCommand( getVMCloseTrayCommand() );
  twc->setVMPreferredUdisksVersion( getVMPreferredUdisksVersion() );

  twc->setUseStringCompareMode( getUseStringCompareMode() );
  twc->setApplyWindowDialogType( getApplyWindowDialogType() );
  twc->setUseExtendedRegEx( getUseExtendedRegEx() );

  twc->setPathJumpAllowDirs( m_pathjump_allow_dirs );
  twc->setPathJumpStoreFilesAlways( getPathJumpStoreFilesAlways() );

  twc->setFaceDB( getFaceDB() );

  twc->setRestoreTabsMode( getRestoreTabsMode() );
  twc->setStoreTabsMode( getStoreTabsMode() );

  twc->setTerminalReturnsEarly( getTerminalReturnsEarly() );

  twc->setDirectoryPresets( getDirectoryPresets() );

  twc->setInitialCommand( m_initial_command );

  twc->setDisableBGCheckPrefix( getDisableBGCheckPrefix() );

  twc->setKVPPool( *m_kvp_pool );

  return twc;
}

void WConfig::setColors(List *ncolors)
{
  WC_Color *tc;
  int id=colors->initEnum();
  tc=(WC_Color*)colors->getFirstElement(id);
  while(tc!=NULL) {
    delete tc;
    tc=(WC_Color*)colors->getNextElement(id);
  }
  colors->closeEnum(id);
  colors->removeAllElements();
  id=ncolors->initEnum();
  tc=(WC_Color*)ncolors->getFirstElement(id);
  while(tc!=NULL) {
    colors->addElement(tc->duplicate());
    tc=(WC_Color*)ncolors->getNextElement(id);
  }
  ncolors->closeEnum(id);
}

List *WConfig::getColors()
{
  return colors;
}

void WConfig::resetColors()
{
  WC_Color *tc;
  int id = colors->initEnum();

  tc = (WC_Color*)colors->getFirstElement( id );
  while ( tc != NULL ) {
    delete tc;
    tc = (WC_Color*)colors->getNextElement( id );
  }
  colors->closeEnum( id );
  colors->removeAllElements();
  colors->addElement( new WC_Color( 160, 160, 160 ) );
  colors->addElement( new WC_Color( 0, 0, 0 ) );
  colors->addElement( new WC_Color( 255, 255, 255 ) );
  colors->addElement( new WC_Color( 0, 85, 187 ) );
  colors->addElement( new WC_Color( 204, 34, 0 ) );
  colors->addElement( new WC_Color( 50, 180, 20 ) );
  colors->addElement( new WC_Color( 119, 0, 119 ) );
  colors->addElement( new WC_Color( 238, 170, 68 ) );
}

void WConfig::setColor( int nr, int red, int green, int blue )
{
  WC_Color *tc;

  if ( ( nr < 0 ) || ( nr > 255 ) ) return;
  while ( colors->size() < ( nr + 1 ) ) colors->addElement( new WC_Color() );
  tc = (WC_Color*)colors->getElementAt( nr );
  if ( tc != NULL ) {
    tc->setRed( red );
    tc->setGreen( green );
    tc->setBlue( blue );
  }
}

bool WConfig::configurePathIndex( int index )
{
  if ( index < 0 ||
       index >= paths->size() ) return false;
  return configurePath( (WCPath*)paths->getElementAt( index ) );
}

bool WConfig::configurePath(WCPath *p1)
{
  WCPath *p1_bak = p1->duplicate();
  WCPath *p1_bak2 = p1->duplicate();
  AGUIX *aguix=worker->getAGUIX();
  int tw,w,h,ty,tx;
  int t1,t2;
  WCDoubleShortkey *dk;
  List *dkeys;
  int id, row, erg;
  AWindow *win;
  char *tstr;
  Requester *req = new Requester( aguix );
  std::string str1;
  bool acceptkey;

  w=10;
  h=10;
  win = new AWindow( aguix, 10, 10, w, h, catalog.getLocale( 82 ), AWindow::AWINDOW_DIALOG );
  win->create();
  ty=5;
  Text *tt1=(Text*)win->add(new Text(aguix,5,ty,catalog.getLocale(83)));
  StringGadget *sg1=(StringGadget*)win->add(new StringGadget(aguix,5+tt1->getWidth()+5,
                                                             ty,100,p1->getName(),0));
  w=sg1->getX()+sg1->getWidth()+5;
  ty+=sg1->getHeight()+5;
  
  t1 = aguix->getTextWidth( "Test" ) + 10;
  SolidButton *sb1=(SolidButton*)win->add(new SolidButton(aguix,5,ty,t1,"Test",
                                                          p1->getFG(),p1->getBG(),false));
  tx=sb1->getX()+sb1->getWidth()+5;
  t1 = aguix->getTextWidth( catalog.getLocale( 32 ) ) + 10;
  Button *b1=(Button*)win->add(new Button(aguix,tx,ty,t1,catalog.getLocale(32),0));
  tx+=b1->getWidth()+5;
  t1 = aguix->getTextWidth( catalog.getLocale( 33 ) ) + 10;
  Button *b2=(Button*)win->add(new Button(aguix,tx,ty,t1,catalog.getLocale(33),0));
  tw=tx+b2->getWidth()+5;
  if(tw>w) w=tw;
  ty+=b2->getHeight()+5;
  t1 = aguix->getTextWidth( catalog.getLocale( 61 ) ) + 10;
  t2 = aguix->getTextWidth( catalog.getLocale( 62 ) ) + 10;
  tw=(t1>t2)?t1:t2;

  tt1 = (Text*)win->add( new Text( aguix, 5, ty, catalog.getLocale( 449 ) ) );
  ty += tt1->getHeight() + 5;
  FieldListView *sklv = (FieldListView*)win->add( new FieldListView( aguix,
                                                                     5,
                                                                     ty,
                                                                     100,
                                                                     6 * aguix->getCharHeight(),
                                                                     0 ) );
  sklv->setNrOfFields( 3 );
  sklv->setFieldWidth( 1, 1 );
  sklv->setHBarState( 2 );
  sklv->setVBarState( 2 );
  
  dkeys = p1_bak2->getDoubleKeys();
  id = dkeys->initEnum();
  dk = (WCDoubleShortkey*)dkeys->getFirstElement( id );
  while ( dk != NULL ) {
    row = sklv->addRow();
    sklv->setPreColors( row, FieldListView::PRECOLOR_ONLYACTIVE );
    tstr = aguix->getNameOfKey( dk->getKeySym( 0 ), dk->getMod( 0 ) );
    if ( tstr != NULL ) {
      sklv->setText( row, 0, tstr );
      _freesafe( tstr );
    } else {
      sklv->setText( row, 0, "???" );
    }
    if ( dk->getType() == WCDoubleShortkey::WCDS_DOUBLE ) {
      tstr = aguix->getNameOfKey( dk->getKeySym( 1 ), dk->getMod( 1 ) );
      if ( tstr != NULL ) {
        sklv->setText( row, 2, tstr );
        _freesafe( tstr );
      } else {
        sklv->setText( row, 2, "???" );
      }
    }
    dk = (WCDoubleShortkey*)dkeys->getNextElement( id );
  }
  dkeys->closeEnum( id );
  sklv->redraw();
  
  tw = sklv->getWidth() + 10;
  if ( tw > w ) w = tw;
  ty += sklv->getHeight();
  
  GUIElement *skbs[2];
  skbs[0] = (Button*)win->add( new Button( aguix, 5, ty, catalog.getLocale( 450 ), 0 ) );
  skbs[1] = (Button*)win->add( new Button( aguix, 5, ty, catalog.getLocale( 451 ), 0 ) );

  ty += skbs[0]->getHeight() + 5;

  tt1=(Text*)win->add(new Text(aguix,5,ty,catalog.getLocale(84)));
  StringGadget *sg2=(StringGadget*)win->add(new StringGadget(aguix,5+tt1->getWidth()+5,ty,100,
                                                             p1->getPath(),0));
  tw=sg2->getX()+sg2->getWidth()+5;
  if(tw>w) w=tw;
  ty+=sg2->getHeight()+5;

  t1 = aguix->getTextWidth( catalog.getLocale( 11 ) ) + 10;
  t2 = aguix->getTextWidth( catalog.getLocale( 8 ) ) + 10;
  tw=5+t1+5+t2+5;
  if(tw>w) w=tw;
  Button *okb=(Button*)win->add(new Button(aguix,
                                             5,
                                             ty,
                                             t1,
                                             catalog.getLocale(11),
                                             0));
  Button *cancelb=(Button*)win->add(new Button(aguix,
                                                 w-5-t2,
                                                 ty,
                                                 t2,
                                                 catalog.getLocale(8),
                                                 0));
  h=okb->getY()+okb->getHeight()+5;

  t1 = AGUIX::scaleElementsW( w, 5, 0, 0, false, true, skbs, NULL, 2 );
  if ( t1 > w ) {
    w = t1;
  }
  sklv->resize( w - 2 * 5, sklv->getHeight() );
  cancelb->move( w - 5 - cancelb->getWidth(), cancelb->getY() );

  win->setDoTabCycling( true );
  win->resize(w,h);
  win->setMaxSize(w,h);
  win->setMinSize(w,h);
  sg1->resize(w-5-sg1->getX(),sg1->getHeight());
  sg2->resize(w-5-sg2->getX(),sg2->getHeight());
  win->show();
  AGMessage *msg;
  while((msg=aguix->GetMessage(NULL))!=NULL) aguix->ReplyMessage(msg);
  int ende=0;
  
  p1->setDoubleKeys( NULL );  // clear list to avoid conflicts
  
  while(ende==0) {
    msg=aguix->WaitMessage(win);
    if(msg!=NULL) {
      if(msg->type==AG_CLOSEWINDOW) {
        if(msg->closewindow.window==win->getWindow()) ende=-1;
      } else if(msg->type==AG_BUTTONCLICKED) {
        if(msg->button.button==okb) ende=1;
        else if(msg->button.button==cancelb) ende=-1;
        else if(msg->button.button==b1) {
          int col=palette(sb1->getFG());
          if(col>=0) sb1->setFG(col);
        } else if(msg->button.button==b2) {
          int col=palette(sb1->getBG());
          if(col>=0) sb1->setBG(col);
        } else if ( msg->button.button == skbs[0] ) {
          // add shortkey
          // 1.Ask for normal or double shortkey
          str1 = catalog.getLocale( 453 );
          str1 += "|";
          str1 += catalog.getLocale( 454 );
          erg = req->request( catalog.getLocale( 123 ),
                              catalog.getLocale( 452 ),
                              str1.c_str() );
          if ( erg == 1 ) {
            // double
            getDoubleShortkey( true, NULL, NULL, p1, &dk );
          } else {
            // normal
            getDoubleShortkey( false, NULL, NULL, p1, &dk );
          }
          if ( dk != NULL ) {
            // if getDoubleShortkey returns a key then
            // it's not used or the user want it to be used here
            // so add it and after okay remove all other conflicts
            acceptkey = false;
            if ( p1_bak2->conflictKey( dk ) == true ) {
              // conflicts with current list
              // inform the user but do not use it
              req->request( catalog.getLocale( 347 ),
                            catalog.getLocale( 457 ),
                            catalog.getLocale( 11 ) );
            } else {
              // doesn't conflict with current list
              acceptkey = true;
            }
            if ( acceptkey == true ) {
              dkeys->addElement( dk );
              row = sklv->addRow();
              sklv->setPreColors( row, FieldListView::PRECOLOR_ONLYACTIVE );
              tstr = aguix->getNameOfKey( dk->getKeySym( 0 ), dk->getMod( 0 ) );
              if ( tstr != NULL ) {
                sklv->setText( row, 0, tstr );
                _freesafe( tstr );
              } else {
                sklv->setText( row, 0, "???" );
              }
              if ( dk->getType() == WCDoubleShortkey::WCDS_DOUBLE ) {
                tstr = aguix->getNameOfKey( dk->getKeySym( 1 ), dk->getMod( 1 ) );
                if ( tstr != NULL ) {
                  sklv->setText( row, 2, tstr );
                  _freesafe( tstr );
                } else {
                  sklv->setText( row, 2, "???" );
                }
              }
            } else {
              delete dk;
            }
            sklv->redraw();
          }
        } else if ( msg->button.button == skbs[1] ) {
          // delete shortkey
          row = sklv->getActiveRow();
          if ( sklv->isValidRow( row ) == true ) {
            dkeys->removeElementAt( row );
            sklv->deleteRow( row );
            sklv->redraw();
          }
        }
      } else if ( msg->type == AG_KEYPRESSED ) {
          if ( win->isParent( msg->key.window, false ) == true ) {
              switch ( msg->key.key ) {
                  case XK_Escape:
                      ende = -1;
                      break;
              }
          }
      }
      aguix->ReplyMessage(msg);
    }
  }
  if(ende==1) {
    // Ubernehmen
    p1->setName(sg1->getText());
    p1->setPath(sg2->getText());

    WCButton *twcb;
    WCHotkey *twch;
    WCPath *twcp;

    // search for existing shortkey and remove it
    id = dkeys->initEnum();
    dk = (WCDoubleShortkey*)dkeys->getFirstElement( id );
    while ( dk != NULL ) {
      if ( findDoubleShortkey( dk, getButtons(), getPaths(), getHotkeys(), &twcb, &twcp, &twch ) != 0 ) {
        if ( twcb != NULL ) {
          twcb->removeKey( dk );
        } else if ( ( twcp != NULL ) && ( twcp != p1 ) ) {
          twcp->removeKey( dk );
        } else if ( twch != NULL ) {
          twch->removeKey( dk );
        }
      }
      dk = (WCDoubleShortkey*)dkeys->getNextElement( id );
    }
    dkeys->closeEnum( id );
    p1->setCheck(true);
    p1->setFG(sb1->getFG());
    p1->setBG(sb1->getBG());
    p1->setDoubleKeys( dkeys );
  } else {
    p1->setDoubleKeys( p1_bak->getDoubleKeys() );
  }
  delete p1_bak;
  delete p1_bak2;
  delete win;
  delete req;
  return (ende==-1)?false:true;
}

bool WConfig::configureHotkeyIndex( int index )
{
  if ( index < 0 ||
       index >= hotkeys->size() ) return false;
  return configureHotkey( (WCHotkey*)hotkeys->getElementAt( index ) );
}

bool WConfig::configureHotkey(WCHotkey *h1)
{
  WCHotkey *h1_bak=h1->duplicate();
  WCHotkey *h1_bak2=h1->duplicate();
  AGUIX *aguix=worker->getAGUIX();
  WCDoubleShortkey *dk;
  List *dkeys;
  int id, row, erg;
  AWindow *win;
  char *tstr;
  Requester *req = new Requester( aguix );
  std::string str1;
  bool acceptkey;
  int lastrow;
  struct timeval tv1, tv2;
  int w, h;

  win = new AWindow( aguix, 10, 10, 10, 10, catalog.getLocale( 91 ), AWindow::AWINDOW_NORMAL );
  win->create();

  AContainer *ac1 = win->setContainer( new AContainer( win, 1, 6 ), true );
  ac1->setMinSpace( 5 );
  ac1->setMaxSpace( 5 );

  AContainer *ac1_1 = ac1->add( new AContainer( win, 2, 1 ), 0, 0 );
  ac1_1->setMinSpace( 5 );
  ac1_1->setMaxSpace( 5 );
  ac1_1->setBorderWidth( 0 );

  ac1_1->add( new Text( aguix, 0, 0, catalog.getLocale( 92 ) ), 0, 0, AContainer::CO_FIX );
  StringGadget *sg1 = (StringGadget*)ac1_1->add( new StringGadget( aguix, 0, 0, 100, h1->getName(), 0 ), 1, 0, AContainer::CO_INCW );
  
  ac1->add( new Text( aguix, 0, 0, catalog.getLocale( 449 ) ), 0, 1, AContainer::CO_INCWNR );

  AContainer *ac1_2 = ac1->add( new AContainer( win, 1, 2 ), 0, 2 );
  ac1_2->setMinSpace( 0 );
  ac1_2->setMaxSpace( 0 );
  ac1_2->setBorderWidth( 0 );

  FieldListView *sklv = (FieldListView*)ac1_2->add( new FieldListView( aguix,
								       0,
								       0,
								       100,
								       6 * aguix->getCharHeight(),
								       0 ), 0, 0, AContainer::CO_MIN );
  sklv->setNrOfFields( 3 );
  sklv->setFieldWidth( 1, 1 );
  sklv->setHBarState( 2 );
  sklv->setVBarState( 2 );
  
  dkeys = h1_bak2->getDoubleKeys();
  id = dkeys->initEnum();
  dk = (WCDoubleShortkey*)dkeys->getFirstElement( id );
  while ( dk != NULL ) {
    row = sklv->addRow();
    sklv->setPreColors( row, FieldListView::PRECOLOR_ONLYACTIVE );
    tstr = aguix->getNameOfKey( dk->getKeySym( 0 ), dk->getMod( 0 ) );
    if ( tstr != NULL ) {
      sklv->setText( row, 0, tstr );
      _freesafe( tstr );
    } else {
      sklv->setText( row, 0, "???" );
    }
    if ( dk->getType() == WCDoubleShortkey::WCDS_DOUBLE ) {
      tstr = aguix->getNameOfKey( dk->getKeySym( 1 ), dk->getMod( 1 ) );
      if ( tstr != NULL ) {
        sklv->setText( row, 2, tstr );
        _freesafe( tstr );
      } else {
        sklv->setText( row, 2, "???" );
      }
    }
    dk = (WCDoubleShortkey*)dkeys->getNextElement( id );
  }
  dkeys->closeEnum( id );
  sklv->redraw();
  
  AContainer *ac1_2_1 = ac1_2->add( new AContainer( win, 2, 1 ), 0, 1 );
  ac1_2_1->setMinSpace( 0 );
  ac1_2_1->setMaxSpace( 0 );
  ac1_2_1->setBorderWidth( 0 );
  
  GUIElement *skbs[2];
  skbs[0] = (Button*)ac1_2_1->add( new Button( aguix, 0, 0, catalog.getLocale( 450 ), 0 ), 0, 0, AContainer::CO_INCW );
  skbs[1] = (Button*)ac1_2_1->add( new Button( aguix, 0, 0, catalog.getLocale( 451 ), 0 ), 1, 0, AContainer::CO_INCW );

  ac1->add( new Text( aguix, 0, 0, catalog.getLocale( 245 ) ), 0, 3, AContainer::CO_INCWNR );

  AContainer *ac1_3 = ac1->add( new AContainer( win, 2, 1 ), 0, 4 );
  ac1_3->setMinSpace( 0 );
  ac1_3->setMaxSpace( 0 );
  ac1_3->setBorderWidth( 0 );

  AContainer *ac1_3_1 = ac1_3->add( new AContainer( win, 1, 5 ), 0, 0 );
  ac1_3_1->setMinSpace( 0 );
  ac1_3_1->setMaxSpace( 0 );
  ac1_3_1->setBorderWidth( 0 );

  Button *b2 = (Button*)ac1_3_1->add( new Button( aguix, 0, 0, catalog.getLocale( 246 ), 0 ), 0, 0, AContainer::CO_INCH );
  Button *b3 = (Button*)ac1_3_1->add( new Button( aguix, 0, 0, catalog.getLocale( 247 ), 0 ), 0, 1, AContainer::CO_INCH );
  Button *b4 = (Button*)ac1_3_1->add( new Button( aguix, 0, 0, catalog.getLocale( 248 ), "button-special1-fg", "button-special1-bg", 0 ), 0, 2, AContainer::CO_INCH );
  Button *b5 = (Button*)ac1_3_1->add( new Button( aguix, 0, 0, catalog.getLocale( 236 ), 0 ), 0, 3, AContainer::CO_INCH );
  Button *b6 = (Button*)ac1_3_1->add( new Button( aguix, 0, 0, catalog.getLocale( 237 ), 0 ), 0, 4, AContainer::CO_INCH );

  FieldListView *lv = (FieldListView*)ac1_3->add( new FieldListView( aguix,
								     0,
								     0,
								     20 * aguix->getTextWidth( "M" ),
								     100,
								     0 ), 1, 0, AContainer::CO_MIN );
  lv->setHBarState(2);
  lv->setVBarState(2);
  lv->setAcceptFocus( true );
  lv->setDisplayFocus( true );
  command_list_t coms=h1->getComs();
  for ( auto &fpr : coms ) {
      row = lv->addRow();
      lv->setPreColors( row, FieldListView::PRECOLOR_ONLYACTIVE );
      lv->setText( row, 0, fpr->getDescription() );
  }
  lv->redraw();

  AContainer *ac1_4 = ac1->add( new AContainer( win, 2, 1 ), 0, 5 );
  ac1_4->setMinSpace( 5 );
  ac1_4->setMaxSpace( -1 );
  ac1_4->setBorderWidth( 0 );
  Button *okb =(Button*)ac1_4->add( new Button( aguix,
                                                0,
                                                0,
                                                catalog.getLocale( 11 ),
                                                0 ), 0, 0, AContainer::CO_FIX );
  Button *cancelb = (Button*)ac1_4->add( new Button( aguix,
						     0,
						     0,
						     catalog.getLocale( 8 ),
						     0 ), 1, 0, AContainer::CO_FIX );


  win->setDoTabCycling( true );
  win->contMaximize( true );

  w = win->getWidth();
  h = win->getHeight();
  if ( ( configureHotkeySize[0] >= w ) && ( configureHotkeySize[1] >= h ) ) {
    win->resize( configureHotkeySize[0], configureHotkeySize[1] );
  }

  win->show();
  AGMessage *msg;
  while((msg=aguix->GetMessage(NULL))!=NULL) aguix->ReplyMessage(msg);
  int ende=0;
  
  h1->setDoubleKeys( NULL );  // clear list to avoid conflicts
  
  lastrow = -1;
  timerclear( &tv1 );
  while(ende==0) {
    msg=aguix->WaitMessage(win);
    if(msg!=NULL) {
      if(msg->type==AG_CLOSEWINDOW) {
        if(msg->closewindow.window==win->getWindow()) ende=-1;
      } else if(msg->type==AG_BUTTONCLICKED) {
        if(msg->button.button==okb) ende=1;
        else if(msg->button.button==cancelb) ende=-1;
        else if(msg->button.button==b2) {
            bool dontConfigure = false;
            auto fpr=requestCommand( dontConfigure );
            if ( fpr ) {
                coms.push_back( fpr );
                if ( ! dontConfigure ) fpr->configureWhenAvail();
                row = lv->addRow();
                lv->setPreColors( row, FieldListView::PRECOLOR_ONLYACTIVE );
                lv->setText( row, 0, fpr->getDescription() );
                lv->setActiveRow( row );
                lv->showActive();
                lv->redraw();
            }
        } else if(msg->button.button==b3) {
          row = lv->getActiveRow();
          if ( lv->isValidRow( row ) == true ) {
              auto it = coms.begin();
              std::advance( it, row );
              coms.erase( it );
              lv->deleteRow( row );
              if ( lv->isValidRow( row ) == true )
                  lv->setActiveRow( row );
              else
                  lv->setActiveRow( row - 1 );
              lv->showActive();
              lv->redraw();
          }
        } else if(msg->button.button==b4) {
          row = lv->getActiveRow();
          if ( lv->isValidRow( row ) == true ) {
              auto fpr = coms.at( row );
              fpr->configure();
              lv->setText( row, 0, fpr->getDescription() );
              lv->redraw();
          }
        } else if(msg->button.button==b5) {
          row = lv->getActiveRow();
          if ( lv->isValidRow( row ) == true ) {
            if ( row > 0 ) {
                auto fpr = coms.at( row );
                coms.at( row ) = coms.at( row - 1 );
                coms.at( row - 1 ) = fpr;
                lv->swapRows( row, row - 1 );
                lv->showActive();
                lv->redraw();
            }
          }
        } else if(msg->button.button==b6) {
          row = lv->getActiveRow();
          if ( lv->isValidRow( row ) == true ) {
            if ( row < ( lv->getElements() - 1 ) ) {
                auto fpr = coms.at( row );
                coms.at( row ) = coms.at( row + 1 );
                coms.at( row + 1 ) = fpr;
                lv->swapRows( row, row + 1 );
                lv->showActive();
                lv->redraw();
            }
          }
        } else if ( msg->button.button == skbs[0] ) {
          // add shortkey
          // 1.Ask for normal or double shortkey
          str1 = catalog.getLocale( 453 );
          str1 += "|";
          str1 += catalog.getLocale( 454 );
          erg = req->request( catalog.getLocale( 123 ),
                              catalog.getLocale( 452 ),
                              str1.c_str() );
          if ( erg == 1 ) {
            // double
            getDoubleShortkey( true, NULL, h1, NULL, &dk );
          } else {
            // normal
            getDoubleShortkey( false, NULL, h1, NULL, &dk );
          }
          if ( dk != NULL ) {
            // if getDoubleShortkey returns a key then
            // it's not used or the user want it to be used here
            // so add it and after okay remove all other conflicts
            acceptkey = false;
            if ( h1_bak2->conflictKey( dk ) == true ) {
              // conflicts with current list
              // inform the user but do not use it
              req->request( catalog.getLocale( 347 ),
                            catalog.getLocale( 457 ),
                            catalog.getLocale( 11 ) );
            } else {
              // doesn't conflict with current list
              acceptkey = true;
            }
            if ( acceptkey == true ) {
              dkeys->addElement( dk );
              row = sklv->addRow();
              sklv->setPreColors( row, FieldListView::PRECOLOR_ONLYACTIVE );
              tstr = aguix->getNameOfKey( dk->getKeySym( 0 ), dk->getMod( 0 ) );
              if ( tstr != NULL ) {
                sklv->setText( row, 0, tstr );
                _freesafe( tstr );
              } else {
                sklv->setText( row, 0, "???" );
              }
              if ( dk->getType() == WCDoubleShortkey::WCDS_DOUBLE ) {
                tstr = aguix->getNameOfKey( dk->getKeySym( 1 ), dk->getMod( 1 ) );
                if ( tstr != NULL ) {
                  sklv->setText( row, 2, tstr );
                  _freesafe( tstr );
                } else {
                  sklv->setText( row, 2, "???" );
                }
              }
            } else {
              delete dk;
            }
            sklv->redraw();
          }
        } else if ( msg->button.button == skbs[1] ) {
          // delete shortkey
          row = sklv->getActiveRow();
          if ( sklv->isValidRow( row ) == true ) {
            dkeys->removeElementAt( row );
            sklv->deleteRow( row );
            sklv->redraw();
          }
        }
      } else if ( msg->type == AG_FIELDLV_ONESELECT ) {
        if ( ( msg->fieldlv.lv == lv ) && ( msg->fieldlv.mouse == true ) ) {
          gettimeofday( &tv2, NULL );
          if ( lastrow < 0 ) {
            lastrow = msg->fieldlv.row;
            tv1 = tv2;
          } else {
            if  ( ( msg->fieldlv.row == lastrow ) &&
                  ( aguix->isDoubleClick( &tv2, &tv1 ) == true ) ) {
              if ( lv->isValidRow( lastrow ) == true ) {
                  auto fpr = coms.at( lastrow );
                  fpr->configure();
                  lv->setText( lastrow, 0, fpr->getDescription() );
                  lv->redraw();
              }
              lastrow = -1;
            } else {
              lastrow = msg->fieldlv.row;
              tv1 = tv2;
            }
          }
        }
      } else if ( msg->type == AG_FIELDLV_MULTISELECT ) {
        lastrow = -1;
      } else if ( msg->type == AG_KEYPRESSED ) {
          if ( win->isParent( msg->key.window, false ) == true ) {
              switch ( msg->key.key ) {
                  case XK_Escape:
                      ende = -1;
                      break;
              }
          }
      }
      aguix->ReplyMessage(msg);
    }
  }
  if(ende==1) {
    // Ubernehmen
    h1->setName(sg1->getText());
    h1->setComs( coms );

    WCButton *twcb;
    WCHotkey *twch;
    WCPath *twcp;

    // search for existing shortkey and remove it
    id = dkeys->initEnum();
    dk = (WCDoubleShortkey*)dkeys->getFirstElement( id );
    while ( dk != NULL ) {
      if ( findDoubleShortkey( dk, getButtons(), getPaths(), getHotkeys(), &twcb, &twcp, &twch ) != 0 ) {
        if ( twcb != NULL ) {
          twcb->removeKey( dk );
        } else if ( twcp != NULL ) {
          twcp->removeKey( dk );
        } else if ( ( twch != NULL ) && ( twch != h1 ) ) {
          twch->removeKey( dk );
        }
      }
      dk = (WCDoubleShortkey*)dkeys->getNextElement( id );
    }
    dkeys->closeEnum( id );
    h1->setDoubleKeys( dkeys );
  } else {
    h1->setComs(h1_bak->getComs());
    h1->setDoubleKeys( h1_bak->getDoubleKeys() );
  }
  delete h1_bak;
  delete h1_bak2;
  configureHotkeySize[0] = win->getWidth();
  configureHotkeySize[1] = win->getHeight();
  delete win;
  delete req;

  return (ende==-1)?false:true;
}

class requestCommand_str {
public:
    std::string str;
    int id;
    std::string internalName;
    std::string category;
    bool hidden;
    int row;
    bool eval_command = false;
    std::string description;

    requestCommand_str() : id( 0 ),
                           hidden( false ),
                           row ( - 1 )
    {
    }

    std::string getVisibleText() const
    {
        if ( ! description.empty() ) {
            std::string t = description;

            t += " (";

            if ( eval_command ) {
                t += catalog.getLocale( 988 );
                t += " ";
            }

            t += str;
            t += ")";

            return t;
        } else {
            return str;
        }
    }

    bool operator<( const requestCommand_str &rhs ) const
    {
        if ( internalName == OwnOp::name &&
             rhs.internalName != OwnOp::name ) {
            return true;
        } else if ( internalName != OwnOp::name &&
             rhs.internalName == OwnOp::name ) {
            return false;
        }

        if ( category < rhs.category ) {
            return true;
        } else if ( category == rhs.category ) {
            return strcasecmp( getVisibleText().c_str(), rhs.getVisibleText().c_str() ) < 0;
        }
        return false;
    }
};

void filter_commands( std::vector< requestCommand_str > &command_list,
                      const std::string &filter )
{
    StringMatcherFlexibleMatch matcher;

    matcher.setMatchString( filter );

    for ( std::vector< requestCommand_str >::iterator it1 = command_list.begin();
          it1 != command_list.end();
          ++it1 ) {

        if ( matcher.match( it1->getVisibleText() ) ) {
            it1->hidden = false;
        } else {
            it1->hidden = true;
        }
    }
}

void prepare_lv( std::vector< requestCommand_str > &command_list,
                 FieldListView &lv )
{
    lv.setSize( 0 );

    for ( std::vector< requestCommand_str >::iterator it1 = command_list.begin();
          it1 != command_list.end();
          ++it1 ) {
        if ( it1->hidden == false ) {
            int row = lv.addRow();

            lv.setText( row, 0, it1->category );
            lv.setText( row, 1, it1->getVisibleText() );
            lv.setPreColors( row, FieldListView::PRECOLOR_ONLYACTIVE );

            it1->row = row;
        }
    }

    lv.redraw();
}

std::shared_ptr< FunctionProto > WConfig::requestCommand( bool &dontConfigure )
{
    AGUIX *aguix = worker->getAGUIX();
    std::shared_ptr< FunctionProto > fpr = NULL;
    AWindow *win;
    std::vector< requestCommand_str > tlist;
    int trow;
  
    win = new AWindow( aguix, 10, 10, 10, 10, catalog.getLocale( 249 ), AWindow::AWINDOW_DIALOG );
    win->create();

    AContainer *ac1 = win->setContainer( new AContainer( win, 1, 3 ), true );
    ac1->setMinSpace( 5 );
    ac1->setMaxSpace( 5 );

    AContainer *ac1_1 = ac1->add( new AContainer( win, 2, 1 ), 0, 0 );
    ac1_1->setMinSpace( 5 );
    ac1_1->setMaxSpace( 5 );
    ac1_1->setBorderWidth( 0 );

    ac1_1->add( new Text( aguix, 0, 0, catalog.getLocale( 793 ) ), 0, 0, AContainer::CO_FIX );
    StringGadget *filter_sg = (StringGadget*)ac1_1->add( new StringGadget( aguix,
                                                                           0,
                                                                           0,
                                                                           50,
                                                                           "",
                                                                           1 ), 1, 0, AContainer::CO_INCW );

    FieldListView *lv = (FieldListView*)ac1->add( new FieldListView( aguix, 0,
                                                                     0,
                                                                     200,
                                                                     200,
                                                                     0 ),
                                                  0, 1, AContainer::CO_MIN );
    lv->setHBarState( 2 );
    lv->setVBarState( 2 );
    lv->setNrOfFields( 2 );
    lv->setGlobalFieldSpace( 5 );
    lv->setShowHeader( true );
    lv->setFieldText( 0, catalog.getLocale( 950 ) );
    lv->setFieldText( 1, catalog.getLocale( 951 ) );

    for ( int i = 0; i < worker->getNrOfCommands(); i++ ) {
        auto tfpr = worker->getCommand4ID( i );
        requestCommand_str ts;
        ts.id = i;
        ts.category = FunctionProto::getCategoryName( tfpr->getCategory() );
        ts.str = tfpr->getDescription();
        ts.internalName = tfpr->getName();
        tlist.push_back( ts );
    }

    {
        auto l = worker->getListOfCommandsWithoutArgs();

        for ( auto &cmd : l ) {
            requestCommand_str ts;
            ts.id = -1;
            ts.category = FunctionProto::getCategoryName( cmd.category );
            ts.str = cmd.name;
            ts.eval_command = true;
            ts.internalName = "eval_command";
            ts.description = cmd.description;
            tlist.push_back( ts );
        }
    }

    std::sort( tlist.begin(),
               tlist.end() );

    filter_commands( tlist, "" );
    prepare_lv( tlist, *lv );

    if ( lastRequestCommand != NULL ) {
        for ( std::vector< requestCommand_str >::iterator it1 = tlist.begin();
              it1 != tlist.end();
              ++it1 ) {
            if ( it1->hidden == false &&
                 it1->str == lastRequestCommand ) {
                lv->setActiveRow( it1->row );
                break;
            }
        }
    }

    lv->maximizeX();
    lv->centerActive();

    ac1->readLimits();

    AContainer *ac1_6 = ac1->add( new AContainer( win, 2, 1 ), 0, 2 );
    ac1_6->setMinSpace( 5 );
    ac1_6->setMaxSpace( -1 );
    ac1_6->setBorderWidth( 0 );
    Button *okb =(Button*)ac1_6->add( new Button( aguix,
                                                  0,
                                                  0,
                                                  catalog.getLocale( 11 ),
                                                  0 ), 0, 0, AContainer::CO_FIX );
    Button *cancelb = (Button*)ac1_6->add( new Button( aguix,
                                                       0,
                                                       0,
                                                       catalog.getLocale( 8 ),
                                                       0 ), 1, 0, AContainer::CO_FIX );

    win->setDoTabCycling( true );
    win->contMaximize( true );

    win->show();

    AGMessage *msg;
    while ( ( msg = aguix->GetMessage( NULL ) ) != NULL ) aguix->ReplyMessage( msg );
    int ende = 0;

    while ( ende == 0 ) {
        msg = aguix->WaitMessage( win );
        if ( msg != NULL ) {
            if ( msg->type == AG_CLOSEWINDOW ) {
                if ( msg->closewindow.window == win->getWindow() ) ende = -1;
            } else if ( msg->type == AG_BUTTONCLICKED ) {
                if ( msg->button.button == okb ) ende = 1;
                else if ( msg->button.button == cancelb ) ende = -1;
            } else if (msg->type == AG_STRINGGADGET_CONTENTCHANGE ) {
                if ( msg->stringgadget.sg == filter_sg ) {
                    filter_commands( tlist, filter_sg->getText() );
                    prepare_lv( tlist, *lv );
                }
            } else if ( msg->type == AG_KEYPRESSED ) {
                if ( win->isParent( msg->key.window, false ) == true ) {
                    switch ( msg->key.key ) {
                        case XK_Escape:
                            ende = -1;
                            break;
                    }
                }
            }

            aguix->ReplyMessage( msg );
        }
    }

    dontConfigure = false;

    if ( ende == 1 ) {
        trow = lv->getActiveRow();
        if ( lv->isValidRow( trow ) == true ) {
            for ( std::vector< requestCommand_str >::iterator it1 = tlist.begin();
                  it1 != tlist.end();
                  ++it1 ) {
                if ( it1->hidden == false &&
                     it1->row == trow ) {
                    if ( it1->eval_command ) {
                        auto tfpr = std::make_shared< ScriptOp >();

                        tfpr->setType( ScriptOp::SCRIPT_EVALCOMMAND );
                        tfpr->setCommandStr( it1->str );

                        fpr = tfpr;

                        dontConfigure = true;
                    } else {
                        fpr = std::shared_ptr< FunctionProto >( worker->getCommand4ID( it1->id ) );
                    }
                    
                    if ( lastRequestCommand != NULL ) _freesafe( lastRequestCommand );
                    lastRequestCommand = dupstring( it1->str.c_str() );

                    break;
                }
            }
        }
    }
    delete win;

    return fpr;
}

bool WConfig::configureButtonIndex( int index )
{
  if ( index < 0 ||
       index >= buttons->size() ) return false;
  return configureButton( (WCButton*)buttons->getElementAt( index ) );
}

bool WConfig::configureButton(WCButton *wcb1)
{
  /*
   * I will clear the doublekey list for wcb1
   * _bak is used to restore keys when canceled
   * changes will be done to
   */
  WCButton *wcb1_bak=wcb1->duplicate();
  WCButton *wcb1_bak2=wcb1->duplicate();
  AGUIX *aguix=worker->getAGUIX();
  int t1;
  WCDoubleShortkey *dk;
  List *dkeys;
  int id, row, erg;
  AWindow *win;
  char *tstr;
  Requester *req = new Requester( aguix );
  std::string str1;
  bool acceptkey;
  int lastrow;
  struct timeval tv1, tv2;
  int w, h;

  win = new AWindow( aguix, 10, 10, 10, 10, catalog.getLocale( 59 ), AWindow::AWINDOW_NORMAL );
  win->create();

  AContainer *ac1 = win->setContainer( new AContainer( win, 1, 7 ), true );
  ac1->setMinSpace( 5 );
  ac1->setMaxSpace( 5 );

  AContainer *ac1_1 = ac1->add( new AContainer( win, 2, 1 ), 0, 0 );
  ac1_1->setMinSpace( 5 );
  ac1_1->setMaxSpace( 5 );
  ac1_1->setBorderWidth( 0 );

  ac1_1->add( new Text( aguix, 0, 0, catalog.getLocale( 60 ) ), 0, 0, AContainer::CO_FIX );
  StringGadget *sg1 = (StringGadget*)ac1_1->add( new StringGadget( aguix,
								   0,
								   0,
								   100,
								   wcb1->getText(),
								   0 ), 1, 0, AContainer::CO_INCW );

  AContainer *ac1_2 = ac1->add( new AContainer( win, 4, 1 ), 0, 1 );
  ac1_2->setMinSpace( 5 );
  ac1_2->setMaxSpace( 5 );
  ac1_2->setBorderWidth( 0 );

  SolidButton *tsb = (SolidButton*)ac1_2->add( new SolidButton( aguix, 0, 0,
								"Test",
								wcb1->getFG(), wcb1->getBG(), false ), 0, 0, AContainer::CO_FIX );
  Button *fgb = (Button*)ac1_2->add( new Button( aguix, 0, 0, catalog.getLocale( 32 ), 0 ), 1, 0, AContainer::CO_FIX );
  Button *bgb = (Button*)ac1_2->add( new Button( aguix, 0, 0, catalog.getLocale( 33 ), 0 ), 2, 0, AContainer::CO_FIX );
  
  ac1->add( new Text( aguix, 0, 0, catalog.getLocale( 449 ) ), 0, 2, AContainer::CO_INCWNR );

  AContainer *ac1_4 = ac1->add( new AContainer( win, 1, 2 ), 0, 3 );
  ac1_4->setMinSpace( 0 );
  ac1_4->setMaxSpace( 0 );
  ac1_4->setBorderWidth( 0 );

  FieldListView *sklv = (FieldListView*)ac1_4->add( new FieldListView( aguix,
								       0,
								       0,
								       100,
								       6 * aguix->getCharHeight(),
								       0 ), 0, 0, AContainer::CO_MIN );
  sklv->setNrOfFields( 3 );
  sklv->setFieldWidth( 1, 1 );
  sklv->setHBarState( 2 );
  sklv->setVBarState( 2 );
  
  // make all key changes to the second copy
  dkeys = wcb1_bak2->getDoubleKeys();
  id = dkeys->initEnum();
  dk = (WCDoubleShortkey*)dkeys->getFirstElement( id );
  while ( dk != NULL ) {
    row = sklv->addRow();
    sklv->setPreColors( row, FieldListView::PRECOLOR_ONLYACTIVE );
    tstr = aguix->getNameOfKey( dk->getKeySym( 0 ), dk->getMod( 0 ) );
    if ( tstr != NULL ) {
      sklv->setText( row, 0, tstr );
      _freesafe( tstr );
    } else {
      sklv->setText( row, 0, "???" );
    }
    if ( dk->getType() == WCDoubleShortkey::WCDS_DOUBLE ) {
      tstr = aguix->getNameOfKey( dk->getKeySym( 1 ), dk->getMod( 1 ) );
      if ( tstr != NULL ) {
        sklv->setText( row, 2, tstr );
        _freesafe( tstr );
      } else {
        sklv->setText( row, 2, "???" );
      }
    }
    dk = (WCDoubleShortkey*)dkeys->getNextElement( id );
  }
  dkeys->closeEnum( id );
  sklv->redraw();
  
  AContainer *ac1_4_1 = ac1_4->add( new AContainer( win, 2, 1 ), 0, 1 );
  ac1_4_1->setMinSpace( 0 );
  ac1_4_1->setMaxSpace( 0 );
  ac1_4_1->setBorderWidth( 0 );

  GUIElement *skbs[2];
  skbs[0] = (Button*)ac1_4_1->add( new Button( aguix, 0, 0, catalog.getLocale( 450 ), 0 ), 0, 0, AContainer::CO_INCW );
  skbs[1] = (Button*)ac1_4_1->add( new Button( aguix, 0, 0, catalog.getLocale( 451 ), 0 ), 1, 0, AContainer::CO_INCW );

  ac1->add( new Text( aguix, 0, 0, catalog.getLocale( 245 ) ), 0, 4, AContainer::CO_INCWNR );

  AContainer *ac1_5 = ac1->add( new AContainer( win, 2, 1 ), 0, 5 );
  ac1_5->setMinSpace( 0 );
  ac1_5->setMaxSpace( 0 );
  ac1_5->setBorderWidth( 0 );

  AContainer *ac1_5_1 = ac1_5->add( new AContainer( win, 1, 5 ), 0, 0 );
  ac1_5_1->setMinSpace( 0 );
  ac1_5_1->setMaxSpace( 0 );
  ac1_5_1->setBorderWidth( 0 );

  Button *b2 = (Button*)ac1_5_1->add( new Button( aguix, 0, 0, catalog.getLocale( 246 ), 0 ), 0, 0, AContainer::CO_INCH );
  Button *b3 = (Button*)ac1_5_1->add( new Button( aguix, 0, 0, catalog.getLocale( 247 ), 0 ), 0, 1, AContainer::CO_INCH );
  Button *b4 = (Button*)ac1_5_1->add( new Button( aguix, 0, 0, catalog.getLocale( 248 ), "button-special1-fg", "button-special1-bg", 0 ), 0, 2, AContainer::CO_INCH );
  Button *b5 = (Button*)ac1_5_1->add( new Button( aguix, 0, 0, catalog.getLocale( 236 ), 0 ), 0, 3, AContainer::CO_INCH );
  Button *b6 = (Button*)ac1_5_1->add( new Button( aguix, 0, 0, catalog.getLocale( 237 ), 0 ), 0, 4, AContainer::CO_INCH );

  FieldListView *lv = (FieldListView*)ac1_5->add( new FieldListView( aguix,
								     0,
								     0,
								     20 * aguix->getTextWidth( "M" ),
								     100,
								     0 ), 1, 0, AContainer::CO_MIN );
  lv->setHBarState(2);
  lv->setVBarState(2);
  lv->setAcceptFocus( true );
  lv->setDisplayFocus( true );
  command_list_t coms = wcb1->getComs();
  for ( auto &fpr : coms ) {
      row = lv->addRow();
      lv->setPreColors( row, FieldListView::PRECOLOR_ONLYACTIVE );
      lv->setText( row, 0, fpr->getDescription() );
  }
  lv->redraw();

  AContainer *ac1_6 = ac1->add( new AContainer( win, 2, 1 ), 0, 6 );
  ac1_6->setMinSpace( 5 );
  ac1_6->setMaxSpace( -1 );
  ac1_6->setBorderWidth( 0 );
  Button *okb =(Button*)ac1_6->add( new Button( aguix,
                                                0,
                                                0,
                                                catalog.getLocale( 11 ),
                                                0 ), 0, 0, AContainer::CO_FIX );
  Button *cancelb = (Button*)ac1_6->add( new Button( aguix,
						     0,
						     0,
						     catalog.getLocale( 8 ),
						     0 ), 1, 0, AContainer::CO_FIX );

  win->setDoTabCycling( true );
  win->contMaximize( true );

  w = win->getWidth();
  h = win->getHeight();
  if ( ( configureButtonSize[0] >= w ) && ( configureButtonSize[1] >= h ) ) {
    win->resize( configureButtonSize[0], configureButtonSize[1] );
  }

  win->show();
  AGMessage *msg;
  while((msg=aguix->GetMessage(NULL))!=NULL) aguix->ReplyMessage(msg);
  int ende=0;
  
  wcb1->setDoubleKeys( NULL );  // clear list to avoid conflicts
  
  lastrow = -1;
  timerclear( &tv1 );
  while(ende==0) {
    msg=aguix->WaitMessage(win);
    if(msg!=NULL) {
      if(msg->type==AG_CLOSEWINDOW) {
        if(msg->closewindow.window==win->getWindow()) ende=-1;
      } else if(msg->type==AG_BUTTONCLICKED) {
        if(msg->button.button==okb) ende=1;
        else if(msg->button.button==cancelb) ende=-1;
        else if(msg->button.button==b2) {
          bool dontConfigure = false;
          auto fpr=requestCommand( dontConfigure );
          if ( fpr ) {
              coms.push_back( fpr );
              if ( ! dontConfigure ) fpr->configureWhenAvail();
              row = lv->addRow();
              lv->setPreColors( row, FieldListView::PRECOLOR_ONLYACTIVE );
              lv->setText( row, 0, fpr->getDescription() );
              lv->setActiveRow( row );
              lv->showActive();
              lv->redraw();
          }
        } else if(msg->button.button==b3) {
          row = lv->getActiveRow();
          if( lv->isValidRow( row ) == true ) {
              auto it = coms.begin();
              std::advance( it, row );
              coms.erase( it );
              lv->deleteRow( row );
              if ( lv->isValidRow( row ) == true )
                  lv->setActiveRow( row );
              else
                  lv->setActiveRow( row - 1 );
              lv->showActive();
              lv->redraw();
          }
        } else if(msg->button.button==b4) {
          row = lv->getActiveRow();
          if( lv->isValidRow( row ) == true ) {
              auto fpr = coms.at( row );
              fpr->configure();
              lv->setText( row, 0, fpr->getDescription() );
              lv->redraw();
          }
        } else if(msg->button.button==b5) {
          row = lv->getActiveRow();
          if ( lv->isValidRow( row ) == true ) {
            if ( row > 0 ) {
                auto fpr = coms.at( row );
                coms.at( row ) = coms.at( row - 1 );
                coms.at( row - 1 ) = fpr;
                lv->swapRows( row, row - 1 );
                lv->showActive();
                lv->redraw();
            }
          }
        } else if(msg->button.button==b6) {
          row = lv->getActiveRow();
          if ( lv->isValidRow( row ) == true ) {
            if ( row < ( lv->getElements() - 1 ) ) {
                auto fpr = coms.at( row );
                coms.at( row ) = coms.at( row + 1 );
                coms.at( row + 1 ) = fpr;
                lv->swapRows( row, row + 1 );
                lv->showActive();
                lv->redraw();
            }
          }
        } else if(msg->button.button==fgb) {
          t1=palette(tsb->getFG());
          if(t1>=0) {
            tsb->setFG(t1);
          }
        } else if(msg->button.button==bgb) {
          t1=palette(tsb->getBG());
          if(t1>=0) {
            tsb->setBG(t1);
          }
        } else if ( msg->button.button == skbs[0] ) {
          // add shortkey
          // 1.Ask for normal or double shortkey
          str1 = catalog.getLocale( 453 );
          str1 += "|";
          str1 += catalog.getLocale( 454 );
          erg = req->request( catalog.getLocale( 123 ),
                              catalog.getLocale( 452 ),
                              str1.c_str() );
          if ( erg == 1 ) {
            // double
            getDoubleShortkey( true, wcb1, NULL, NULL, &dk );
          } else {
            // normal
            getDoubleShortkey( false, wcb1, NULL, NULL, &dk );
          }
          if ( dk != NULL ) {
            // if getDoubleShortkey returns a key then
            // it's not used or the user want it to be used here
            // so add it and after okay remove all other conflicts
            acceptkey = false;
            if ( wcb1_bak2->conflictKey( dk ) == true ) {
              // conflicts with current list
              // inform the user but do not use it
              req->request( catalog.getLocale( 347 ),
                            catalog.getLocale( 457 ),
                            catalog.getLocale( 11 ) );
            } else {
              // doesn't conflict with current list
              acceptkey = true;
            }
            if ( acceptkey == true ) {
              dkeys->addElement( dk );
              row = sklv->addRow();
              sklv->setPreColors( row, FieldListView::PRECOLOR_ONLYACTIVE );
              tstr = aguix->getNameOfKey( dk->getKeySym( 0 ), dk->getMod( 0 ) );
              if ( tstr != NULL ) {
                sklv->setText( row, 0, tstr );
                _freesafe( tstr );
              } else {
                sklv->setText( row, 0, "???" );
              }
              if ( dk->getType() == WCDoubleShortkey::WCDS_DOUBLE ) {
                tstr = aguix->getNameOfKey( dk->getKeySym( 1 ), dk->getMod( 1 ) );
                if ( tstr != NULL ) {
                  sklv->setText( row, 2, tstr );
                  _freesafe( tstr );
                } else {
                  sklv->setText( row, 2, "???" );
                }
              }
            } else {
              delete dk;
            }
            sklv->redraw();
          }
        } else if ( msg->button.button == skbs[1] ) {
          // delete shortkey
          row = sklv->getActiveRow();
          if ( sklv->isValidRow( row ) == true ) {
            dkeys->removeElementAt( row );
            sklv->deleteRow( row );
            sklv->redraw();
          }
        }
      } else if ( msg->type == AG_FIELDLV_ONESELECT ) {
        if ( ( msg->fieldlv.lv == lv ) && ( msg->fieldlv.mouse == true ) ) {
          gettimeofday( &tv2, NULL );
          if ( lastrow < 0 ) {
            lastrow = msg->fieldlv.row;
            tv1 = tv2;
          } else {
            if  ( ( msg->fieldlv.row == lastrow ) &&
                  ( aguix->isDoubleClick( &tv2, &tv1 ) == true ) ) {
              if ( lv->isValidRow( lastrow ) == true ) {
                  auto fpr = coms.at( lastrow );
                  fpr->configure();
                  lv->setText( lastrow, 0, fpr->getDescription() );
                  lv->redraw();
              }
              lastrow = -1;
            } else {
              lastrow = msg->fieldlv.row;
              tv1 = tv2;
            }
          }
        }
      } else if ( msg->type == AG_FIELDLV_MULTISELECT ) {
        lastrow = -1;
      } else if ( msg->type == AG_KEYPRESSED ) {
          if ( win->isParent( msg->key.window, false ) == true ) {
              switch ( msg->key.key ) {
                  case XK_Escape:
                      ende = -1;
                      break;
              }
          }
      }
      aguix->ReplyMessage(msg);
    }
  }
  if(ende==1) {
    // Ubernehmen
    wcb1->setText(sg1->getText());
    wcb1->setFG(tsb->getFG());
    wcb1->setBG(tsb->getBG());
    wcb1->setCheck(true);
    wcb1->setComs( coms );

    WCButton *twcb;
    WCHotkey *twch;
    WCPath *twcp;

    // search for existing shortkey and remove it
    id = dkeys->initEnum();
    dk = (WCDoubleShortkey*)dkeys->getFirstElement( id );
    while ( dk != NULL ) {
      if ( findDoubleShortkey( dk, getButtons(), getPaths(), getHotkeys(), &twcb, &twcp, &twch ) != 0 ) {
        if ( ( twcb != NULL ) && ( twcb != wcb1 ) ) {
          twcb->removeKey( dk );
        } else if ( twcp != NULL ) {
          twcp->removeKey( dk );
        } else if ( twch != NULL ) {
          twch->removeKey( dk );
        }
      }
      dk = (WCDoubleShortkey*)dkeys->getNextElement( id );
    }
    dkeys->closeEnum( id );
    wcb1->setDoubleKeys( dkeys );
  } else {
    wcb1->setComs(wcb1_bak->getComs());
    wcb1->setDoubleKeys( wcb1_bak->getDoubleKeys() );
  }
  delete wcb1_bak;
  delete wcb1_bak2;
  configureButtonSize[0] = win->getWidth();
  configureButtonSize[1] = win->getHeight();
  delete win;
  delete req;
  
  return (ende==-1)?false:true;
}

bool WConfig::configureFiletype(WCFiletype *ft1, int default_panel)
{
  WCFiletype *ft1_bak=ft1->duplicate();
  AGUIX *aguix=worker->getAGUIX();
  int w,h;
  int t1;
  AWindow *win;
  int lastrow, row;
  struct timeval tv1, tv2;
  int trow;
  const int cfixnr = AContainer::CO_FIX +
                     AContainer::ACONT_NORESIZE;
  const int cfixwminh = AContainer::ACONT_MINH +
                        AContainer::ACONT_MINW +
                        AContainer::ACONT_MAXW;
  Text *ftc[4];
  Button *ftcb[4][2];
  int i;
  FileRequester *freq;

  w=10;
  h=10;
  win = new AWindow( aguix, 10, 10, w, h, catalog.getLocale( 88 ), AWindow::AWINDOW_NORMAL );
  win->create();

  AContainer *ac1 = win->setContainer( new AContainer( win, 1, 7 ), true );
  ac1->setMinSpace( 5 );
  ac1->setMaxSpace( 5 );

  bool name_supports_flags = true;
  
  AContainer *ac1_1 = ac1->add( new AContainer( win, name_supports_flags ? 3 : 2, 1 ), 0, 0 );
  ac1_1->setMinSpace( 5 );
  ac1_1->setMaxSpace( 5 );
  ac1_1->setBorderWidth( 0 );

  ac1_1->add( new Text( aguix, 0, 0, catalog.getLocale( 89 ) ), 0, 0, AContainer::CO_FIX );
  StringGadget *sg1 = (StringGadget*)ac1_1->add( new StringGadget( aguix, 0,
                                                                   0, 100, ft1->getName().c_str(), 0 ), 1, 0, AContainer::CO_INCW );
  Button *sg1_flag_b = NULL;

  if ( name_supports_flags ) {
      sg1_flag_b = ac1_1->addWidget( new Button( aguix, 0, 0, catalog.getLocale( 897 ), 0 ),
                                     2, 0, AContainer::CO_FIX );
  }

  ac1->add( new Text( aguix, 0, 0, catalog.getLocale( 250 ) ), 0, 1, AContainer::CO_INCWNR );

  AContainer *ac1_7 = ac1->add( new AContainer( win, 1, 2 ), 0, 2 );
  ac1_7->setMinSpace( 0 );
  ac1_7->setMaxSpace( 0 );
  ac1_7->setBorderWidth( 0 );

  FieldListView *lv0 = (FieldListView*)ac1_7->add( new FieldListView( aguix, 0, 0, 100, 80, 0 ), 0, 0, AContainer::CO_MIN );
  lv0->setHBarState(2);
  lv0->setVBarState(2);
  for ( t1 = 0; t1 < 14; t1++ ) {
    trow = lv0->addRow();
    lv0->setPreColors( trow, FieldListView::PRECOLOR_ONLYACTIVE );
    lv0->setText( trow, 0, catalog.getLocale( 251 + t1 ) );
  }
  lv0->redraw();
  lv0->setActiveRow( 1 );
  
  std::list<std::string> custom_names;
  ft1->fillNamesOfCustomActions( false, custom_names );
  
  for ( std::list<std::string>::iterator it1 = custom_names.begin();
        it1 != custom_names.end();
        it1++ ) {
      trow = lv0->addRow();
      lv0->setPreColors( trow, FieldListView::PRECOLOR_ONLYACTIVE );
      lv0->setText( trow, 0, *it1 );
  }
  
  AContainer *ac1_7_1 = ac1_7->add( new AContainer( win, 2, 1 ), 0, 1 );
  ac1_7_1->setMinSpace( 0 );
  ac1_7_1->setMaxSpace( 0 );
  ac1_7_1->setBorderWidth( 0 );
  Button *new_action_b = (Button*)ac1_7_1->add( new Button( aguix, 0, 0, catalog.getLocale( 777 ), 0 ), 0, 0, AContainer::CO_INCW );
  Button *del_action_b = (Button*)ac1_7_1->add( new Button( aguix, 0, 0, catalog.getLocale( 778 ), 0 ), 1, 0, AContainer::CO_INCW );
  
  ac1->add( new Text( aguix, 0, 0, catalog.getLocale( 245 ) ), 0, 3, AContainer::CO_INCWNR );

  AContainer *ac1_2 = ac1->add( new AContainer( win, 2, 1 ), 0, 4 );
  ac1_2->setMinSpace( 0 );
  ac1_2->setMaxSpace( 0 );
  ac1_2->setBorderWidth( 0 );
  AContainer *ac1_2_1 = ac1_2->add( new AContainer( win, 1, 5 ), 0, 0 );
  ac1_2_1->setMinSpace( 0 );
  ac1_2_1->setMaxSpace( 0 );
  ac1_2_1->setBorderWidth( 0 );
  Button *b2 = (Button*)ac1_2_1->add( new Button( aguix, 0, 0, catalog.getLocale( 246 ), 0 ), 0, 0, cfixwminh );
  Button *b3 = (Button*)ac1_2_1->add( new Button( aguix, 0, 0, catalog.getLocale( 247 ), 0 ), 0, 1, cfixwminh );
  Button *b4 = (Button*)ac1_2_1->add( new Button( aguix, 0, 0, catalog.getLocale( 248 ), "button-special1-fg", "button-special1-bg", 0 ), 0, 2, cfixwminh );
  Button *b5 = (Button*)ac1_2_1->add( new Button( aguix, 0, 0, catalog.getLocale( 236 ), 0 ), 0, 3, cfixwminh );
  Button *b6 = (Button*)ac1_2_1->add( new Button( aguix, 0, 0, catalog.getLocale( 237 ), 0 ), 0, 4, cfixwminh );
  FieldListView *lv = (FieldListView*)ac1_2->add( new FieldListView( aguix,
                                                                     0,
                                                                     0,
                                                                     50,
                                                                     20,
                                                                     0 ), 1, 0, AContainer::CO_MIN );
  lv->setHBarState(2);
  lv->setVBarState(2);
  lv->setAcceptFocus( true );
  lv->setDisplayFocus( true );

  Kartei *k1 = new Kartei( aguix, 10, 10, 10, 10, "" );
  ac1->add( k1, 0, 5, AContainer::CO_MIN );
  k1->create();

  AWindow *subwin12 = new AWindow( aguix, 0, 0, 10, 10, "" );
  k1->add( subwin12 );
  subwin12->create();
  
  AContainer *ac1_3 = subwin12->setContainer( new AContainer( subwin12, 1, 6 ), true );
  ac1_3->setMinSpace( 5 );
  ac1_3->setMaxSpace( 5 );
  ac1_3->setBorderWidth( 5 );
  AContainer *ac1_3_1 = ac1_3->add( new AContainer( subwin12, 3, 1 ), 0, 0 );
  ac1_3_1->setMinSpace( 5 );
  ac1_3_1->setMaxSpace( 5 );
  ac1_3_1->setBorderWidth( 0 );
  ac1_3_1->add( new Text( aguix, 0, 0, catalog.getLocale( 93 ) ), 0, 0, AContainer::CO_FIX );
  StringGadget *sg2=(StringGadget*)ac1_3_1->add( new StringGadget( aguix, 0,
                                                                   0,
                                                                   100,
                                                                   ft1->getPattern(), 0 ), 1, 0, AContainer::CO_INCW );
  ChooseButton *cb1 = (ChooseButton*)ac1_3_1->add( new ChooseButton( aguix, 0,
                                                                     0, ft1->getUsePattern(),
                                                                     catalog.getLocale( 94 ), LABEL_LEFT, 1 ), 2, 0,
                                                                     cfixnr );
  
  ChooseButton *cb11 = (ChooseButton*)ac1_3->add( new ChooseButton( aguix,
                                                                    0,
                                                                    0,
                                                                    ft1->getPatternIgnoreCase(),
                                                                    catalog.getLocale( 501 ),
                                                                    LABEL_RIGHT,
                                                                    1 ), 0, 1, AContainer::CO_INCWNR );
  
  ChooseButton *cb12 = (ChooseButton*)ac1_3->add( new ChooseButton( aguix,
                                                                    0,
                                                                    0,
                                                                    ft1->getPatternUseRegExp(),
                                                                    catalog.getLocale( 502 ),
                                                                    LABEL_RIGHT,
                                                                    1 ), 0, 2, AContainer::CO_INCWNR );

  ChooseButton *cb13 = (ChooseButton*)ac1_3->add( new ChooseButton( aguix,
                                                                    0,
                                                                    0,
                                                                    ft1->getPatternUseFullname(),
                                                                    catalog.getLocale( 570 ),
                                                                    LABEL_RIGHT,
                                                                    1 ), 0, 3, AContainer::CO_INCWNR );
  ChooseButton *comma_sep_cb = ac1_3->addWidget( new ChooseButton( aguix,
                                                                   0,
                                                                   0,
                                                                   ft1->getPatternIsCommaSeparated(),
                                                                   catalog.getLocale( 1133 ),
                                                                   LABEL_RIGHT,
                                                                   1 ), 0, 4, AContainer::CO_INCWNR );
  Button *patternhb = (Button*)ac1_3->add( new Button( aguix,
                                                       0,
			 		  	       0,
				 		       catalog.getLocale( 483 ),
						       0 ), 0, 5, AContainer::CO_INCWNR );

  AWindow *subwin13 = new AWindow( aguix, 0, 0, 10, 10, "" );
  k1->add( subwin13 );
  subwin13->create();
  
  AContainer *acsw13 = subwin13->setContainer( new AContainer( subwin13, 1, 1 ), true );
  acsw13->setMinSpace( 5 );
  acsw13->setMaxSpace( 5 );
  acsw13->setBorderWidth( 5 );

  AContainer *ac1_4 = acsw13->add( new AContainer( subwin13, 2, 1 ), 0, 0 ); 
  ac1_4->setMinSpace( 5 );
  ac1_4->setMaxSpace( 5 );
  ac1_4->setBorderWidth( 0 );
  Button *b7 = (Button*)ac1_4->add( new Button( aguix, 0, 0, catalog.getLocale( 95 ), 0 ), 0, 0, AContainer::CO_INCW );
  ChooseButton *cb2 = (ChooseButton*)ac1_4->add( new ChooseButton( aguix, 0,
                                                                   0, ft1->getUseFiledesc(),
                                                                   catalog.getLocale( 96 ), LABEL_LEFT, 1 ), 1, 0,
                                                                   cfixnr );

  /************
   * libmagic *
   ************/

  AWindow *subwin16 = new AWindow( aguix, 0, 0, 10, 10, "" );
  k1->add( subwin16 );
  subwin16->create();
  
  AContainer *acsw16 = subwin16->setContainer( new AContainer( subwin16, 1, 6 ), true );
  acsw16->setMinSpace( 5 );
  acsw16->setMaxSpace( 5 );
  acsw16->setBorderWidth( 5 );

  AContainer *ac1_4_2_1 = acsw16->add( new AContainer( subwin16, 3, 1 ), 0, 0 ); 
  ac1_4_2_1->setMinSpace( 5 );
  ac1_4_2_1->setMaxSpace( 5 );
  ac1_4_2_1->setBorderWidth( 0 );
  ac1_4_2_1->add( new Text( aguix, 0, 0, catalog.getLocale( 795 ) ), 0, 0, AContainer::CO_FIX );
  StringGadget *magic_sg = (StringGadget*)ac1_4_2_1->add( new StringGadget( aguix, 0,
                                                                          0,
                                                                          100,
                                                                          ft1->getMagicPattern().c_str(), 0 ), 1, 0, AContainer::CO_INCW );
  ChooseButton *magic_cb = (ChooseButton*)ac1_4_2_1->add( new ChooseButton( aguix, 0,
                                                                            0, ft1->getUseMagic(),
                                                                            catalog.getLocale( 796 ), LABEL_LEFT, 1 ),
                                                          2, 0, cfixnr );
  
  AContainer *magic_options_cont = acsw16->add( new AContainer( subwin16, 3, 1 ), 0, 1 ); 
  magic_options_cont->setMinSpace( 5 );
  magic_options_cont->setMaxSpace( 5 );
  magic_options_cont->setBorderWidth( 0 );
  ChooseButton *magic_compressed_cb = magic_options_cont->addWidget( new ChooseButton( aguix, 0,
                                                                                       0, ft1->getMagicCompressed(),
                                                                                       catalog.getLocale( 811 ), LABEL_RIGHT, 1 ),
                                                                     0, 0, AContainer::CO_INCWNR );
  ChooseButton *magic_mime_cb = magic_options_cont->addWidget( new ChooseButton( aguix, 0,
                                                                                 0, ft1->getMagicMime(),
                                                                                 catalog.getLocale( 1013 ), LABEL_RIGHT, 1 ),
                                                               1, 0, AContainer::CO_INCWNR );
  ChooseButton *magic_ignore_case_cb = magic_options_cont->addWidget( new ChooseButton( aguix, 0,
                                                                                        0, ft1->getMagicIgnoreCase(),
                                                                                        catalog.getLocale( 501 ), LABEL_RIGHT, 1 ),
                                                                      2, 0, AContainer::CO_INCWNR );

  acsw16->add( new BevelBox( aguix, 0, 0, 100, 2, 0 ), 0, 2, AContainer::CO_INCW );

  AContainer *ac1_4_2_2 = acsw16->add( new AContainer( subwin16, 3, 1 ), 0, 3 ); 
  ac1_4_2_2->setMinSpace( 5 );
  ac1_4_2_2->setMaxSpace( 5 );
  ac1_4_2_2->setBorderWidth( 0 );
  ac1_4_2_2->add( new Text( aguix, 0, 0, catalog.getLocale( 797 ) ), 0, 0, AContainer::CO_FIX );
  StringGadget *magic_testfile_sg = (StringGadget*)ac1_4_2_2->add( new StringGadget( aguix, 0,
                                                                                     0,
                                                                                     100,
                                                                                     "", 0 ), 1, 0, AContainer::CO_INCW );
  Button *magic_file_test_b = (Button*)ac1_4_2_2->add( new Button( aguix,
                                                                   0, 0,
                                                                   catalog.getLocale( 458 ),
                                                                   0 ), 2, 0, AContainer::CO_FIX );

  AContainer *ac1_4_2_3 = acsw16->add( new AContainer( subwin16, 2, 1 ), 0, 4 ); 
  ac1_4_2_3->setMinSpace( 5 );
  ac1_4_2_3->setMaxSpace( 5 );
  ac1_4_2_3->setBorderWidth( 0 );
  ac1_4_2_3->add( new Text( aguix, 0, 0, catalog.getLocale( 798 ) ), 0, 0, AContainer::CO_FIX );
  StringGadget *magic_output_sg = (StringGadget*)ac1_4_2_3->add( new StringGadget( aguix, 0,
                                                                                   0,
                                                                                   100,
                                                                                   "", 0 ), 1, 0, AContainer::CO_INCW );

  AContainer *ac1_4_2_4 = acsw16->add( new AContainer( subwin16, 4, 1 ), 0, 5 ); 
  ac1_4_2_4->setMinSpace( 5 );
  ac1_4_2_4->setMaxSpace( 5 );
  ac1_4_2_4->setBorderWidth( 0 );
  ac1_4_2_4->add( new Text( aguix, 0, 0, catalog.getLocale( 799 ) ), 0, 0, AContainer::CO_FIX );
  Text *magic_matches_text = (Text*)ac1_4_2_4->add( new Text( aguix, 0, 0, "" ), 1, 0, AContainer::CO_INCW );
  Button *magic_check_b = (Button*)ac1_4_2_4->add( new Button( aguix,
                                                               0, 0,
                                                               catalog.getLocale( 800 ),
                                                               0 ), 2, 0, AContainer::CO_FIX );
  Button *magic_help_b = (Button*)ac1_4_2_4->add( new Button( aguix,
                                                              0, 0,
                                                              catalog.getLocale( 483 ),
                                                              0 ), 3, 0, AContainer::CO_FIX );

  AWindow *subwin14 = new AWindow( aguix, 0, 0, 10, 10, "" );
  k1->add( subwin14 );
  subwin14->create();
  
  AContainer *acsw14 = subwin14->setContainer( new AContainer( subwin14, 1, 2 ), true );
  acsw14->setMinSpace( 5 );
  acsw14->setMaxSpace( 5 );
  acsw14->setBorderWidth( 5 );

  AContainer *ac1_6 = acsw14->add( new AContainer( subwin14, 3, 1 ), 0, 0 );
  ac1_6->setMinSpace( 5 );
  ac1_6->setMaxSpace( 5 );
  ac1_6->setBorderWidth( 0 );
  ac1_6->add( new Text( aguix, 0, 0, catalog.getLocale( 573 ) ), 0, 0, AContainer::CO_FIX );
  
  AContainer *ac1_6_1 = ac1_6->add( new AContainer( subwin14, 2, 1 ), 1, 0 );
  ac1_6_1->setMinSpace( 0 );
  ac1_6_1->setMaxSpace( 0 );
  ac1_6_1->setBorderWidth( 0 );
  StringGadget *sg3=(StringGadget*)ac1_6_1->add( new StringGadget( aguix, 0,
                                                                   0,
                                                                   100,
                                                                   ft1->getExtCond(), 0 ), 0, 0, AContainer::CO_INCW );
  Button *flagb = (Button*)ac1_6_1->add( new Button( aguix,
                                                     0, 0,
                                                     "F",
                                                     0 ), 1, 0, AContainer::CO_FIX );
  ChooseButton *cb3 = (ChooseButton*)ac1_6->add( new ChooseButton( aguix, 0,
                                                                   0, ft1->getUseExtCond(),
                                                                   catalog.getLocale( 574 ), LABEL_LEFT, 1 ), 2, 0,
                                                                   cfixnr );
  Button *exthb = (Button*)acsw14->add( new Button( aguix,
                                                    0,
		   		   	            0,
				 		    catalog.getLocale( 483 ),
						    0 ), 0, 1, AContainer::CO_INCWNR );

  AWindow *subwin15 = new AWindow( aguix, 0, 0, 10, 10, "" );
  k1->add( subwin15 );
  subwin15->create();
  
  AContainer *acsw15 = subwin15->setContainer( new AContainer( subwin15, 1, 4 ), true );
  acsw15->setMinSpace( 5 );
  acsw15->setMaxSpace( 5 );
  acsw15->setBorderWidth( 5 );

  AContainer *ac15_1 = acsw15->add( new AContainer( subwin15, 2, 1 ), 0, 0 );
  ac15_1->setMinSpace( 5 );
  ac15_1->setMaxSpace( 5 );
  ac15_1->setBorderWidth( 0 );
  ac15_1->add( new Text( aguix, 0, 0, catalog.getLocale( 601 ) ), 0, 0, AContainer::CO_FIX );
  CycleButton *cyftc = (CycleButton*)ac15_1->add( new CycleButton( aguix,
								   0,
								   0,
								   100,
								   0 ), 1, 0, AContainer::CO_INCW );
  cyftc->addOption( catalog.getLocale( 602 ) );
  cyftc->addOption( catalog.getLocale( 603 ) );
  cyftc->addOption( catalog.getLocale( 604 ) );
  cyftc->addOption( catalog.getLocale( 605 ) );
  cyftc->resize( cyftc->getMaxSize(), cyftc->getHeight() );
  ac15_1->readLimits();

  acsw15->add( new Text( aguix, 0, 0, catalog.getLocale( 606 ) ), 0, 1, AContainer::CO_INCWNR );
  
  AContainer *ac15_2 = acsw15->add( new AContainer( subwin15, 3, 4 ), 0, 2 );
  ac15_2->setMinSpace( 5 );
  ac15_2->setMaxSpace( 5 );
  ac15_2->setBorderWidth( 0 );
  
  ftc[0] = (Text*)ac15_2->add( new Text( aguix,
					 0, 0,
					 catalog.getLocale( 607 ),
					 ft1->getCustomColor( 0 )[0], ft1->getCustomColor( 1 )[0] ), 0, 0, AContainer::CO_FIX );
  ftc[1] = (Text*)ac15_2->add( new Text( aguix,
					 0, 0,
					 catalog.getLocale( 608 ),
					 ft1->getCustomColor( 0 )[1], ft1->getCustomColor( 1 )[1] ), 0, 1, AContainer::CO_FIX );
  ftc[2] = (Text*)ac15_2->add( new Text( aguix,
					 0, 0,
					 catalog.getLocale( 609 ),
					 ft1->getCustomColor( 0 )[2], ft1->getCustomColor( 1 )[2] ), 0, 2, AContainer::CO_FIX );
  ftc[3] = (Text*)ac15_2->add( new Text( aguix,
					 0, 0,
					 catalog.getLocale( 610 ),
					 ft1->getCustomColor( 0 )[3], ft1->getCustomColor( 1 )[3] ), 0, 3, AContainer::CO_FIX );

  for ( i = 0; i < 4; i++ ) {
    ftcb[i][0] = (Button*)ac15_2->add( new Button( aguix,
						   0,
						   0,
						   catalog.getLocale( 32 ),
						   0 ), 1, i, AContainer::CO_INCW );
    ftcb[i][1] = (Button*)ac15_2->add( new Button( aguix,
						   0,
						   0,
						   catalog.getLocale( 33 ),
						   0 ), 2, i, AContainer::CO_INCW );
  }

  AContainer *ac15_3 = acsw15->add( new AContainer( subwin15, 2, 1 ), 0, 3 );
  ac15_3->setMinSpace( 5 );
  ac15_3->setMaxSpace( 5 );
  ac15_3->setBorderWidth( 0 );

  ac15_3->add( new Text( aguix, 0, 0, catalog.getLocale( 611 ) ), 0, 0, AContainer::CO_FIX );

  AContainer *ac15_3_1 = ac15_3->add( new AContainer( subwin15, 3, 1 ), 1, 0 );
  ac15_3_1->setMinSpace( 0 );
  ac15_3_1->setMaxSpace( 0 );
  ac15_3_1->setBorderWidth( 0 );

  Button *ftcsb = (Button*)ac15_3_1->add( new Button( aguix,
						      0,
						      0,
						      catalog.getLocale( 458 ),
						      0 ), 0, 0, AContainer::CO_FIX );
  StringGadget *ftcsg = (StringGadget*)ac15_3_1->add( new StringGadget( aguix, 0,
									0, 100,
									( ft1->getColorExt() != NULL ) ? ft1->getColorExt() : "",
									0 ), 1, 0, AContainer::CO_INCW );
  Button *ftchb = (Button*)ac15_3_1->add( new Button( aguix,
						      0,
						      0,
						      catalog.getLocale( 483 ),
						      0 ), 2, 0, AContainer::CO_FIX );

  switch ( ft1->getColorMode() ) {
  case WCFiletype::CUSTOMCOL:
    cyftc->setOption( 1 );
    break;
  case WCFiletype::EXTERNALCOL:
    cyftc->setOption( 2 );
    break;
  case WCFiletype::PARENTCOL:
    cyftc->setOption( 3 );
    break;
  default:
    cyftc->setOption( 0 );
    break;
  }

  /****************
   * priority tab *
   ****************/

  AWindow *subwin17 = new AWindow( aguix, 0, 0, 10, 10, "" );
  k1->add( subwin17 );
  subwin17->create();
  
  AContainer *acsw17 = subwin17->setContainer( new AContainer( subwin17, 1, 1 ), true );
  acsw17->setMinSpace( 5 );
  acsw17->setMaxSpace( 5 );
  acsw17->setBorderWidth( 5 );

  AContainer *acsw17_1 = acsw17->add( new AContainer( subwin17, 2, 1 ), 0, 0 );
  acsw17_1->setMinSpace( 5 );
  acsw17_1->setMaxSpace( 5 );
  acsw17_1->setBorderWidth( 0 );
  acsw17_1->add( new Text( aguix, 0, 0, catalog.getLocale( 1359 ) ), 0, 0, AContainer::CO_FIX );
  
  AContainer *acsw17_1_1 = acsw17_1->add( new AContainer( subwin17, 4, 1 ), 1, 0 );
  acsw17_1_1->setMinSpace( 0 );
  acsw17_1_1->setMaxSpace( 0 );
  acsw17_1_1->setBorderWidth( 0 );
  std::string priostr = AGUIXUtils::formatStringToString( "%d", ft1->priority() );
  StringGadget *priosg = acsw17_1_1->addWidget( new StringGadget( aguix, 0,
                                                                  0,
                                                                  100,
                                                                  priostr.c_str(), 0 ), 0, 0, AContainer::CO_INCW );
  Button *highpriob = acsw17_1_1->addWidget( new Button( aguix,
                                                         0, 0,
                                                         catalog.getLocale( 1356 ),
                                                         0 ), 1, 0, AContainer::CO_FIX );
  Button *defaultpriob = acsw17_1_1->addWidget( new Button( aguix,
                                                            0, 0,
                                                            catalog.getLocale( 1357 ),
                                                            0 ), 2, 0, AContainer::CO_FIX );
  Button *lowpriob = acsw17_1_1->addWidget( new Button( aguix,
                                                        0, 0,
                                                        catalog.getLocale( 1358 ),
                                                        0 ), 3, 0, AContainer::CO_FIX );

  k1->setOption( subwin12, 0, catalog.getLocale( 575 ) );
  k1->setOption( subwin13, 1, catalog.getLocale( 95 ) );
  k1->setOption( subwin16, 2, catalog.getLocale( 803 ) );
  k1->setOption( subwin14, 3, catalog.getLocale( 576 ) );
  k1->setOption( subwin15, 4, catalog.getLocale( 612 ) );
  k1->setOption( subwin17, 5, catalog.getLocale( 1360 ) );
  k1->maximize();
  k1->contMaximize();
  ac1->readLimits();

  AContainer *ac1_5 = ac1->add( new AContainer( win, 2, 1 ), 0, 6 );
  ac1_5->setMinSpace( 5 );
  ac1_5->setMaxSpace( -1 );
  ac1_5->setBorderWidth( 0 );
  Button *okb =(Button*)ac1_5->add( new Button( aguix,
                                                0,
                                                0,
                                                catalog.getLocale( 11 ),
                                                0 ), 0, 0, AContainer::CO_FIX );
  Button *cancelb = (Button*)ac1_5->add( new Button( aguix,
                                                     0,
                                                     0,
                                                     catalog.getLocale( 8 ),
                                                     0 ), 1, 0, AContainer::CO_FIX );
  win->setDoTabCycling( true );
  win->contMaximize( true );
  w = win->getWidth();
  h = win->getHeight();

  if ( ( configureFiletypeSize[0] >= w ) && ( configureFiletypeSize[1] >= h ) ) {
    win->resize( configureFiletypeSize[0], configureFiletypeSize[1] );
  }

  w = win->getWidth();
  h = win->getHeight();

  win->show();
  k1->show();

  if ( default_panel >= 0 && default_panel <= 4 ) {
      k1->optionChange( default_panel );
  }

  AGMessage *msg;
  while((msg=aguix->GetMessage(NULL))!=NULL) aguix->ReplyMessage(msg);
  int ende=0;
  command_list_t coms;
  std::string current_actionname;
  
  trow = lv0->getActiveRow();
  if ( lv0->isValidRow( trow ) == true ) {
      showFTActions( lv0->getText( trow, 0 ).c_str(), ft1, lv, &coms, current_actionname );
  }

  freq = new FileRequester( aguix );

  lastrow = -1;
  timerclear( &tv1 );
  while(ende==0) {
    msg=aguix->WaitMessage(win);
    if(msg!=NULL) {
      if(msg->type==AG_CLOSEWINDOW) {
        if(msg->closewindow.window==win->getWindow()) ende=-1;
      } else if(msg->type==AG_BUTTONCLICKED) {
        if(msg->button.button==okb) ende=1;
        else if(msg->button.button==cancelb) ende=-1;
        else if(msg->button.button==b2) {
            bool dontConfigure = false;
            auto fpr=requestCommand( dontConfigure );
            if(fpr!=NULL) {
                coms.push_back( fpr );
                if ( ! dontConfigure ) fpr->configureWhenAvail();
                row = lv->addRow();
                lv->setPreColors( row, FieldListView::PRECOLOR_ONLYACTIVE );
                lv->setText( row, 0, fpr->getDescription() );
                lv->setActiveRow( row );
                lv->showActive();
                lv->redraw();
            }
        } else if(msg->button.button==b3) {
            row = lv->getActiveRow();
            if ( lv->isValidRow( row ) == true ) {
                auto it = coms.begin();
                std::advance( it, row );
                coms.erase( it );
                lv->deleteRow( row );
                if ( lv->isValidRow( row ) == true )
                    lv->setActiveRow( row );
                else
                    lv->setActiveRow( row - 1 );
                lv->showActive();
                lv->redraw();
            }
        } else if(msg->button.button==b4) {
            row = lv->getActiveRow();
            if ( lv->isValidRow( row ) == true ) {
                auto fpr = coms.at( row );
                fpr->configure();
                lv->setText( row, 0, fpr->getDescription() );
                lv->redraw();
            }
        } else if(msg->button.button==b5) {
            row = lv->getActiveRow();
            if ( lv->isValidRow( row ) == true ) {
                if ( row > 0 ) {
                    auto fpr = coms.at( row );
                    coms.at( row ) = coms.at( row - 1 );
                    coms.at( row - 1 ) = fpr;
                    lv->swapRows( row, row - 1 );
                    lv->showActive();
                    lv->redraw();
                }
            }
        } else if(msg->button.button==b6) {
            row = lv->getActiveRow();
            if ( lv->isValidRow( row ) == true ) {
                if ( row < ( lv->getElements() - 1 ) ) {
                    auto fpr = coms.at( row );
                    coms.at( row ) = coms.at( row + 1 );
                    coms.at( row + 1 ) = fpr;
                    lv->swapRows( row, row + 1 );
                    lv->showActive();
                    lv->redraw();
                }
            }
        } else if(msg->button.button==b7) {
          if(changeFiledesc(ft1)==true) {
            cb2->setState(1);
          }
        } else if ( msg->button.button == patternhb ) {
          Requester *req = new Requester( aguix, win );
          req->request( catalog.getLocale( 575 ),
                        catalog.getLocale( 577 ),
                        catalog.getLocale( 11 ) );
          delete req;
        } else if ( msg->button.button == exthb ) {
          Requester *req = new Requester( aguix, win );
          req->request( catalog.getLocale( 576 ),
                        catalog.getLocale( 593 ),
                        catalog.getLocale( 11 ) );
          delete req;
        } else if ( msg->button.button == flagb ) {
          sg3->insertAtCursor( CondParser::requestFlag() );
	} else if ( msg->button.button == ftcsb ) {
	  if ( freq->request_entry( catalog.getLocale( 265 ),
				    NULL,
				    catalog.getLocale( 11 ),
				    catalog.getLocale( 8 ),
				    catalog.getLocale( 265 ),
				    true ) > 0 ) {
	    std::string str1 = freq->getLastEntryStr();
	    if ( str1.length() > 0 ) {
	      const char *newstr1 = ftcsg->getText();
	      char *newstr2;
	      int pos = ftcsg->getCursor();
	      
	      newstr2 = (char*)_allocsafe( strlen( newstr1 ) + strlen( str1.c_str() ) + 1 );
	      strncpy( newstr2, newstr1, pos );
	      strcpy( newstr2 + pos, str1.c_str() );
	      strcpy( newstr2 + pos + strlen( str1.c_str() ), newstr1 + pos );
	      ftcsg->setText( newstr2 );
	      _freesafe( newstr2 );
	    }
	  }
        } else if ( msg->button.button == ftchb ) {
          Requester *req = new Requester( aguix, win );
          req->request( catalog.getLocale( 576 ),
                        catalog.getLocale( 613 ),
                        catalog.getLocale( 11 ) );
          delete req;
        } else if ( msg->button.button == new_action_b ) {
            std::string new_name = queryNewActionName();
            if ( new_name.length() > 0 ) {
                auto res = ft1->getCustomActions( new_name );
                if ( res.second == false ) {
                    ft1->setCustomActions( new_name, {} );

                    trow = lv0->addRow();
                    lv0->setPreColors( trow, FieldListView::PRECOLOR_ONLYACTIVE );
                    lv0->setText( trow, 0, new_name );
                    lv0->setActiveRow( trow );
                    lv0->showActive();
                    showFTActions( new_name.c_str(), ft1, lv, &coms, current_actionname );
                }
            }
        } else if ( msg->button.button == del_action_b ) {
            trow = lv0->getActiveRow();
            //TODO do not use hard coded number of actions
            if ( lv0->isValidRow( trow ) == true && trow >= 14 ) {
                std::string cname = lv0->getText( trow, 0 );
                ft1->removeCustomAction( cname );
                lv0->deleteRow( trow );
                current_actionname = "";

                lv0->setActiveRow( trow - 1 );
                trow = lv0->getActiveRow();
                if ( lv0->isValidRow( trow ) == true ) {
                    showFTActions( lv0->getText( trow, 0 ).c_str(), ft1, lv, &coms, current_actionname );
                }
                lv0->redraw();
            }
        } else if ( msg->button.button == magic_file_test_b ) {
            if ( freq->request_entry( catalog.getLocale( 265 ),
                                      NULL,
                                      catalog.getLocale( 11 ),
                                      catalog.getLocale( 8 ),
                                      catalog.getLocale( 265 ),
                                      false ) > 0 ) {
                std::string str1 = freq->getLastEntryStr();
                if ( str1.length() > 0 ) {
                    magic_testfile_sg->setText( str1.c_str() );
                }
            }
        } else if ( msg->button.button == magic_check_b ) {
            std::string testfile = magic_testfile_sg->getText();
            if ( Datei::fileExists( testfile.c_str() ) == true ) {
                int flags = 0;
                if ( magic_compressed_cb->getState() ) {
                    flags |= MagicDB::DECOMPRESS;
                }
                if ( magic_mime_cb->getState() ) {
                    flags |= MagicDB::USE_MIME;
                }

                std::string magic_result = MagicDB::getInstance().getInfo( testfile,
                                                                           flags );
                magic_output_sg->setText( magic_result.c_str() );

                ft1->setMagicPattern( magic_sg->getText() );
                ft1->setMagicIgnoreCase( magic_ignore_case_cb->getState() );
                if ( ft1->magicMatch( magic_result ) == true ) {
                    magic_matches_text->setText( catalog.getLocale( 801 ) );
                } else {
                    magic_matches_text->setText( catalog.getLocale( 802 ) );
                }
            }
        } else if ( msg->button.button == magic_help_b ) {
            Requester *req = new Requester( aguix, win );
            req->request( catalog.getLocale( 803 ),
                          catalog.getLocale( 804 ),
                          catalog.getLocale( 11 ) );
            delete req;
        } else if ( sg1_flag_b && msg->button.button == sg1_flag_b ) {
            insertFileTypeFlag( sg1, ft1 );
        } else if ( msg->button.button == highpriob ) {
            priosg->setText( "-10" );
        } else if ( msg->button.button == defaultpriob ) {
            priosg->setText( "0" );
        } else if ( msg->button.button == lowpriob ) {
            priosg->setText( "10" );
        } else {
	  for ( i = 0; i < 4; i++ ) {
	    if ( msg->button.button == ftcb[i][0] ) {
	      int col = palette( ftc[i]->getFG() );
	      if ( col >= 0 ) {
		ftc[i]->setFG( col );
		cyftc->setOption( 1 );
	      }
	    } else if ( msg->button.button == ftcb[i][1] ) {
	      int col = palette( ftc[i]->getBG() );
	      if ( col >= 0 ) {
		ftc[i]->setBG( col );
		cyftc->setOption( 1 );
	      }
	    }
          }
        }
      } else if(msg->type==AG_STRINGGADGET_DEACTIVATE) {
        if(msg->stringgadget.sg==sg2) cb1->setState(1);
        else if ( msg->stringgadget.sg == sg3 ) cb3->setState( 1 );
	else if ( msg->stringgadget.sg == ftcsg ) cyftc->setOption( 2 );
	else if ( msg->stringgadget.sg == magic_sg ) magic_cb->setState( 1 );
      } else if ( msg->type == AG_SIZECHANGED ) {
      } else if ( ( msg->type == AG_FIELDLV_ONESELECT ) || ( msg->type == AG_FIELDLV_MULTISELECT ) ) {
        if ( ( msg->type == AG_FIELDLV_ONESELECT ) &&
	     ( msg->fieldlv.lv == lv ) &&
	     ( msg->fieldlv.mouse == true ) ) {
          gettimeofday( &tv2, NULL );
          if ( lastrow < 0 ) {
            lastrow = msg->fieldlv.row;
            tv1 = tv2;
          } else {
              if  ( ( msg->fieldlv.row == lastrow ) &&
                    ( aguix->isDoubleClick( &tv2, &tv1 ) == true ) ) {
                  if ( lv->isValidRow( lastrow ) == true ) {
                      auto fpr = coms.at( lastrow );
                      fpr->configure();
                      lv->setText( lastrow, 0, fpr->getDescription() );
                      lv->redraw();
                  }
                  lastrow = -1;
              } else {
                  lastrow = msg->fieldlv.row;
                  tv1 = tv2;
              }
          }
        } else if ( msg->fieldlv.lv == lv0 ) {
          // Nur das Aktions-LV interessiert
          trow = lv0->getActiveRow();
          if ( lv0->isValidRow( trow ) == true ) {
              showFTActions( lv0->getText( trow, 0 ).c_str(), ft1, lv, &coms, current_actionname );
          }
        }
      } else if ( msg->type == AG_FIELDLV_MULTISELECT ) {
        lastrow = -1;
      } else if ( msg->type == AG_CHOOSECLICKED ) {
          if ( msg->choose.button == comma_sep_cb &&
               msg->choose.state == true ) {
              cb12->setState( false );
          } else if ( msg->choose.button == cb12 &&
                      msg->choose.state == true ) {
              comma_sep_cb->setState( false );
          }
      } else if ( msg->type == AG_KEYPRESSED ) {
          if ( win->isParent( msg->key.window, false ) == true ) {
              switch ( msg->key.key ) {
                  case XK_Escape:
                      ende = -1;
                      break;
              }
          }
      }
      aguix->ReplyMessage(msg);
    }
  }
  if(ende==1) {
    // Uebernehmen
    showFTActions( NULL, ft1, lv, &coms, current_actionname );

    ft1->setName(sg1->getText());
    ft1->setPattern(sg2->getText());
    ft1->setUsePattern( cb1->getState() );
    ft1->setPatternIgnoreCase( cb11->getState() );
    ft1->setPatternUseRegExp( cb12->getState() );
    ft1->setPatternUseFullname( cb13->getState() );
    ft1->setUseFiledesc( cb2->getState() );
    ft1->setExtCond( sg3->getText() );
    ft1->setUseExtCond( cb3->getState() );

    switch ( cyftc->getSelectedOption() ) {
      case 1:
        ft1->setColorMode( WCFiletype::CUSTOMCOL );
	for ( i = 0; i < 4; i++ ) {
	  ft1->setCustomColor( 0, i, ftc[i]->getFG() );
	  ft1->setCustomColor( 1, i, ftc[i]->getBG() );
	}
        break;
      case 2:
        ft1->setColorMode( WCFiletype::EXTERNALCOL );
	ft1->setColorExt( ftcsg->getText() );
	break;
      case 3:
        ft1->setColorMode( WCFiletype::PARENTCOL );
	break;
      default:
        ft1->setColorMode( WCFiletype::DEFAULTCOL );
        break;
    }

    ft1->setMagicPattern( magic_sg->getText() );
    ft1->setUseMagic( magic_cb->getState() );
    ft1->setMagicCompressed( magic_compressed_cb->getState() );
    ft1->setMagicMime( magic_mime_cb->getState() );
    ft1->setMagicIgnoreCase( magic_ignore_case_cb->getState() );
    ft1->setPatternIsCommaSeparated( comma_sep_cb->getState() );
    ft1->setPriority( atoi( priosg->getText() ) );
  } else {
    ft1->setDNDActions(ft1_bak->getDNDActions());
    ft1->setDoubleClickActions(ft1_bak->getDoubleClickActions());
    ft1->setShowActions(ft1_bak->getShowActions());
    ft1->setRawShowActions(ft1_bak->getRawShowActions());
    ft1->setUserActions(0,ft1_bak->getUserActions(0));
    ft1->setUserActions(1,ft1_bak->getUserActions(1));
    ft1->setUserActions(2,ft1_bak->getUserActions(2));
    ft1->setUserActions(3,ft1_bak->getUserActions(3));
    ft1->setUserActions(4,ft1_bak->getUserActions(4));
    ft1->setUserActions(5,ft1_bak->getUserActions(5));
    ft1->setUserActions(6,ft1_bak->getUserActions(6));
    ft1->setUserActions(7,ft1_bak->getUserActions(7));
    ft1->setUserActions(8,ft1_bak->getUserActions(8));
    ft1->setUserActions(9,ft1_bak->getUserActions(9));
    ft1->setFiledesc(ft1_bak->getFiledesc());

    ft1->clearCustomActions();

    std::list<std::string> names;
    ft1_bak->fillNamesOfCustomActions( false, names );

    std::list<std::string>::const_iterator cit1;
    for ( cit1 = names.begin(); cit1 != names.end(); cit1++ ) {
	ft1->setCustomActions( *cit1, ft1_bak->getCustomActions( *cit1 ).first );
    }
    ft1->setMagicPattern( ft1_bak->getMagicPattern() );
    ft1->setUseMagic( ft1_bak->getUseMagic() );
    ft1->setMagicCompressed( ft1_bak->getMagicCompressed() );
    ft1->setMagicMime( ft1_bak->getMagicMime() );
    ft1->setMagicIgnoreCase( ft1_bak->getMagicIgnoreCase() );
    ft1->setPatternIsCommaSeparated( ft1_bak->getPatternIsCommaSeparated() );
    ft1->setPriority( ft1_bak->priority() );
  }
  delete ft1_bak;
  configureFiletypeSize[0] = win->getWidth();
  configureFiletypeSize[1] = win->getHeight();
  delete win;

  delete freq;

  return (ende==-1)?false:true;
}

void WConfig::showFTActions( const char *actionname,
                             WCFiletype *ft,
                             FieldListView *lv1,
                             command_list_t *return_list,
                             std::string &write_back_name )
{
    command_list_t l1;
    int row;

    if ( return_list != NULL && ! write_back_name.empty() ){
        // store current list content to action name
        if ( write_back_name == catalog.getLocale(251) ) {
            // DND
            ft->setDNDActions( *return_list );
        } else if ( write_back_name == catalog.getLocale(252) ) {
            // DoubleClick
            ft->setDoubleClickActions( *return_list );
        } else if ( write_back_name == catalog.getLocale(253) ) {
            // Show
            ft->setShowActions( *return_list );
        } else if ( write_back_name == catalog.getLocale(254) ) {
            // RawShow
            ft->setRawShowActions( *return_list );
        } else if ( write_back_name == catalog.getLocale(255) ) {
            // User0
            ft->setUserActions( 0, *return_list );
        } else if ( write_back_name == catalog.getLocale(256) ) {
            // User1
            ft->setUserActions( 1, *return_list );
        } else if ( write_back_name == catalog.getLocale(257) ) {
            // User2
            ft->setUserActions( 2, *return_list );
        } else if ( write_back_name == catalog.getLocale(258) ) {
            // User3
            ft->setUserActions( 3, *return_list );
        } else if ( write_back_name == catalog.getLocale(259) ) {
            // User4
            ft->setUserActions( 4, *return_list );
        } else if ( write_back_name == catalog.getLocale(260) ) {
            // User5
            ft->setUserActions( 5, *return_list );
        } else if ( write_back_name == catalog.getLocale(261) ) {
            // User6
            ft->setUserActions( 6, *return_list );
        } else if ( write_back_name == catalog.getLocale(262) ) {
            // User7
            ft->setUserActions( 7, *return_list );
        } else if ( write_back_name == catalog.getLocale(263) ) {
            // User8
            ft->setUserActions( 8, *return_list );
        } else if ( write_back_name == catalog.getLocale(264) ) {
            // User9
            ft->setUserActions( 9, *return_list );
        } else {
            ft->setCustomActions( write_back_name, *return_list  );
        }
    }

    if ( actionname ) {
        if(strcmp(actionname,catalog.getLocale(251))==0) {
            // DND
            l1=ft->getDNDActions();
        } else if(strcmp(actionname,catalog.getLocale(252))==0) {
            // DoubleClick
            l1=ft->getDoubleClickActions();
        } else if(strcmp(actionname,catalog.getLocale(253))==0) {
            // Show
            l1=ft->getShowActions();
        } else if(strcmp(actionname,catalog.getLocale(254))==0) {
            // RawShow
            l1=ft->getRawShowActions();
        } else if(strcmp(actionname,catalog.getLocale(255))==0) {
            // User0
            l1=ft->getUserActions(0);
        } else if(strcmp(actionname,catalog.getLocale(256))==0) {
            // User1
            l1=ft->getUserActions(1);
        } else if(strcmp(actionname,catalog.getLocale(257))==0) {
            // User2
            l1=ft->getUserActions(2);
        } else if(strcmp(actionname,catalog.getLocale(258))==0) {
            // User3
            l1=ft->getUserActions(3);
        } else if(strcmp(actionname,catalog.getLocale(259))==0) {
            // User4
            l1=ft->getUserActions(4);
        } else if(strcmp(actionname,catalog.getLocale(260))==0) {
            // User5
            l1=ft->getUserActions(5);
        } else if(strcmp(actionname,catalog.getLocale(261))==0) {
            // User6
            l1=ft->getUserActions(6);
        } else if(strcmp(actionname,catalog.getLocale(262))==0) {
            // User7
            l1=ft->getUserActions(7);
        } else if(strcmp(actionname,catalog.getLocale(263))==0) {
            // User8
            l1=ft->getUserActions(8);
        } else if(strcmp(actionname,catalog.getLocale(264))==0) {
            // User9
            l1=ft->getUserActions(9);
        } else {
            l1 = ft->getCustomActions( actionname ).first;
        }

        lv1->setSize( 0 );
        for ( auto &fpr : l1 ) {
            row = lv1->addRow();
            lv1->setPreColors( row, FieldListView::PRECOLOR_ONLYACTIVE );
            lv1->setText( row, 0, fpr->getDescription() );
        }
        lv1->redraw();
    }

    if ( return_list != NULL ) *return_list = l1;
    if ( actionname ) {
        write_back_name = actionname;
    }
}

bool WConfig::changeFiledesc(WCFiletype *ft)
{
  WCFiletype *ft_bak=ft->duplicate();
  AGUIX *aguix=worker->getAGUIX();
  short *filedesc=ft->getFiledesc();
  int tw,w,h,ty;
  int t1,t2;
  char *str;
  AWindow *win;
  int trow;
  
  w=100;
  h=10;
  win = new AWindow( aguix, 10, 10, w, h, catalog.getLocale( 101 ), AWindow::AWINDOW_DIALOG );
  win->create();
  ty=5;
  FieldListView *lv = (FieldListView*)win->add( new FieldListView( aguix, 5, ty, w - 10, 150, 0 ) );
  lv->setHBarState(2);
  lv->setVBarState(2);
  for(t1=0;t1<64;t1++) {
    str=getStr4Char(t1,filedesc[t1]);
    trow = lv->addRow();
    lv->setPreColors( trow, FieldListView::PRECOLOR_ONLYACTIVE );
    lv->setText( trow, 0, str );
    _freesafe(str);
  }
  lv->redraw();
  ty+=lv->getHeight()+5;
  
  t1 = aguix->getTextWidth( catalog.getLocale( 98 ) ) + 10;
  Button *b1=(Button*)win->add(new Button(aguix,5,ty,t1,catalog.getLocale(98),0));
  t2=b1->getWidth();
  t1 = aguix->getTextWidth( catalog.getLocale( 99 ) ) + 10;
  Button *b2=(Button*)win->add(new Button(aguix,5+t2+5,ty,t1,catalog.getLocale(99),0));
  tw=b2->getX()+b2->getWidth()+5;
  if(tw>w) w=tw;
  ty+=b2->getHeight()+5;
  t1 = aguix->getTextWidth( catalog.getLocale( 100 ) ) + 10;
  if((t1+10)<w) t1=w-10;
  Button *b3=(Button*)win->add(new Button(aguix,5,ty,t1,catalog.getLocale(100),0));
  tw=b3->getX()+b3->getWidth()+5;
  if(tw>w) w=tw;
  ty+=b3->getHeight()+5;

  t1 = aguix->getTextWidth( catalog.getLocale( 11 ) ) + 10;
  t2 = aguix->getTextWidth( catalog.getLocale( 8 ) ) + 10;
  tw=5+t1+5+t2+5;
  if(tw>w) w=tw;
  Button *okb=(Button*)win->add(new Button(aguix,
                                             5,
                                             ty,
                                             t1,
                                             catalog.getLocale(11),
                                             0));
  Button *cancelb=(Button*)win->add(new Button(aguix,
                                                 w-5-t2,
                                                 ty,
                                                 t2,
                                                 catalog.getLocale(8),
                                                 0));
  h=okb->getY()+okb->getHeight()+5;
  win->setDoTabCycling( true );
  win->resize(w,h);
  win->setMaxSize(w,h);
  win->setMinSize(w,h);
  lv->resize(w-10,lv->getHeight());
  b2->move(w-5-b2->getWidth(),b2->getY());
  win->show();
  AGMessage *msg;
  while((msg=aguix->GetMessage(NULL))!=NULL) aguix->ReplyMessage(msg);
  int ende=0;
  while(ende==0) {
    msg=aguix->WaitMessage(win);
    if(msg!=NULL) {
      if(msg->type==AG_CLOSEWINDOW) {
        if(msg->closewindow.window==win->getWindow()) ende=-1;
      } else if(msg->type==AG_BUTTONCLICKED) {
        if(msg->button.button==okb) ende=1;
        else if(msg->button.button==cancelb) ende=-1;
        else if(msg->button.button==b1) {
          trow = lv->getActiveRow();
          if ( lv->isValidRow( trow ) == true ) {
            t2 = WCEditByte( filedesc[trow] );
            if(t2>=0) {
              filedesc[trow] = t2;
              str=getStr4Char( trow,t2);
              lv->setText( trow, 0, str );
              _freesafe(str);
              lv->redraw();
            }
          }
        } else if(msg->button.button==b2) {
          trow = lv->getActiveRow();
          if ( lv->isValidRow( trow ) == true ) {
            t2=-1;
            filedesc[trow] = t2;
            str = getStr4Char( trow, t2 );
            lv->setText( trow, 0, str );
            _freesafe(str);
            lv->redraw();
          }
        } else if(msg->button.button==b3) {
          win->hide();
          if(FTautocreate(ft)==true) {
            for(t1=0;t1<64;t1++) {
              str=getStr4Char(t1,filedesc[t1]);
              lv->setText( t1, 0, str );
              _freesafe(str);
            }
            lv->redraw();
          }
          win->show();
        }
      }
      aguix->ReplyMessage(msg);
    }
  }
  if(ende==-1) {
    ft->setFiledesc(ft_bak->getFiledesc());
  } else {
    for(t1=63;t1>=0;t1--) {
      if(filedesc[t1]>=0) {
        if(t1<63) filedesc[t1+1]=-2;
        break;
      }
    }
    if ( t1 < 1 ) if ( filedesc[0] < 0 ) filedesc[0] = -2;
  }
  delete ft_bak;
  delete win;
  return (ende==-1)?false:true;
}

char *WConfig::getStr4Char(int index2,short ch)
{
  char *str = (char*)_allocsafe( A_BYTESFORNUMBER( index2 ) + 1 + strlen( catalog.getLocale( 97 ) ) + 2 + 1 );
  char buf[ A_BYTESFORNUMBER( int ) + 1 + A_BYTESFORNUMBER( char ) ];
  std::string str1;
  
  sprintf(str,"%2d.%s: ",index2,catalog.getLocale(97));
  str1 = str;
  _freesafe( str );
  if(ch>=0) {
    sprintf(buf,"%3d %c",ch,ch);
    str1 += buf;
  }
  return dupstring( str1.c_str() );
}

int WConfig::WCEditByte(int ch)
{
  int return_byte;
  AGUIX *aguix=worker->getAGUIX();
  int tw,w,h,ty;
  int t1,t2;
  char buf[ A_BYTESFORNUMBER( int ) ];

  w=100;
  h=10;
  AWindow *win = new AWindow( aguix, 10, 10, w, h, catalog.getLocale( 98 ), AWindow::AWINDOW_DIALOG );
  win->create();
  ty=5;
  Text *tt1=(Text*)win->add(new Text(aguix,5,ty,catalog.getLocale(102)));
  ty+=tt1->getHeight()+5;
  tw=tt1->getWidth()+10;
  if(tw>w) w=tw;
  if(ch>=0) sprintf(buf,"%d",ch); else buf[0]=0;
  t1 = aguix->getTextWidth( "000000" ) + 10;
  StringGadget *sg=(StringGadget*)win->add(new StringGadget(aguix,5,ty,t1,buf,0));
  if(ch>=0) sprintf(buf,"%c",ch); else buf[0]=0;
  tt1=(Text*)win->add(new Text(aguix,sg->getX()+sg->getWidth()+5,ty,buf));
  tw=tt1->getX()+tt1->getWidth()+5;
  if(tw>w) w=tw;
  ty+=sg->getHeight()+5;

  t1 = aguix->getTextWidth( catalog.getLocale( 11 ) ) + 10;
  t2 = aguix->getTextWidth( catalog.getLocale( 8 ) ) + 10;
  tw=5+t1+5+t2+5;
  if(tw>w) w=tw;
  Button *okb=(Button*)win->add(new Button(aguix,
                                             5,
                                             ty,
                                             t1,
                                             catalog.getLocale(11),
                                             0));
  Button *cancelb=(Button*)win->add(new Button(aguix,
                                                 w-5-t2,
                                                 ty,
                                                 t2,
                                                 catalog.getLocale(8),
                                                 0));
  h=okb->getY()+okb->getHeight()+5;
  win->setDoTabCycling( true );
  win->resize(w,h);
  win->setMaxSize(w,h);
  win->setMinSize(w,h);
  win->show();
  AGMessage *msg;
  while((msg=aguix->GetMessage(NULL))!=NULL) aguix->ReplyMessage(msg);
  int ende=0;
  return_byte=ch;
  while(ende==0) {
    msg=aguix->WaitMessage(win);
    if(msg!=NULL) {
      if(msg->type==AG_CLOSEWINDOW) {
        if(msg->closewindow.window==win->getWindow()) ende=-1;
      } else if(msg->type==AG_BUTTONCLICKED) {
        if(msg->button.button==okb) ende=1;
        else if(msg->button.button==cancelb) ende=-1;
      } else if(msg->type==AG_STRINGGADGET_DEACTIVATE) {
        t1=-1;
        sscanf(sg->getText(),"%d",&t1);
        if(t1<0) t1=0;
        else if(t1>255) t1=255;
        sprintf(buf,"%d",t1);
        sg->setText(buf);
        sprintf(buf,"%c",t1);
        tt1->setText(buf);
        return_byte=t1;
      } else if(msg->type==AG_KEYPRESSED) {
        if(sg->isActive()==false) {
          t1=msg->key.key;
          if(t1<=0xff) {
            sprintf(buf,"%d",t1);
            sg->setText(buf);
            sprintf(buf,"%c",t1);
            tt1->setText(buf);
            return_byte=t1;
          }
        }
      }
      aguix->ReplyMessage(msg);
    }
  }
  delete win;
  return (ende==-1)?-1:return_byte;
}

bool WConfig::FTautocreate(WCFiletype *ft)
{
  AGUIX *aguix = worker->getAGUIX();
  int w, h;
  int i, e;
  char *str;
  AWindow *win;
  FileRequester *frq = new FileRequester( aguix );
  bool dirSet = false;

  w = 100;
  h = 10;
  win = new AWindow( aguix, 10, 10, w, h, catalog.getLocale( 100 ), AWindow::AWINDOW_DIALOG );
  win->create();
  AContainer *ac1 = win->setContainer( new AContainer( win, 1, 4 ), true );
  ac1->setMinSpace( 5 );
  ac1->setMaxSpace( 5 );
  
  ac1->add( new Text( aguix, 0, 0, catalog.getLocale( 614 ) ), 0, 0, AContainer::CO_INCWNR );
  FieldListView *lv = (FieldListView*)ac1->add( new FieldListView( aguix,
								   0, 0,
								   50, 150,
								   0 ), 0, 1, AContainer::CO_MIN );
  lv->setHBarState( 2 );
  lv->setVBarState( 2 );

  AContainer *ac1_2 = ac1->add( new AContainer( win, 2, 1 ), 0, 2 );
  ac1_2->setMinSpace( 5 );
  ac1_2->setMaxSpace( 5 );
  ac1_2->setBorderWidth( 0 );
  Button *addb =(Button*)ac1_2->add( new Button( aguix,
						 0,
						 0,
						 catalog.getLocale( 615 ),
						 0 ), 0, 0, AContainer::CO_INCW );
  Button *delb = (Button*)ac1_2->add( new Button( aguix,
						  0,
						  0,
						  catalog.getLocale( 616 ),
						  0 ), 1, 0, AContainer::CO_INCW );

  AContainer *ac1_3 = ac1->add( new AContainer( win, 2, 1 ), 0, 3 );
  ac1_3->setMinSpace( 5 );
  ac1_3->setMaxSpace( -1 );
  ac1_3->setBorderWidth( 0 );
  Button *okb =(Button*)ac1_3->add( new Button( aguix,
                                                0,
                                                0,
                                                catalog.getLocale( 11 ),
                                                0 ), 0, 0, AContainer::CO_FIX );
  Button *cancelb = (Button*)ac1_3->add( new Button( aguix,
                                                     0,
                                                     0,
                                                     catalog.getLocale( 8 ),
                                                     0 ), 1, 0, AContainer::CO_FIX );
  win->setDoTabCycling( true );
  win->contMaximize( true );
  win->show();
  
  AGMessage *msg;
  while((msg=aguix->GetMessage(NULL))!=NULL) aguix->ReplyMessage(msg);
  int ende=0;
  while(ende==0) {
    msg=aguix->WaitMessage(win);
    if(msg!=NULL) {
      if(msg->type==AG_CLOSEWINDOW) {
        if(msg->closewindow.window==win->getWindow()) ende=-1;
      } else if(msg->type==AG_BUTTONCLICKED) {
        if(msg->button.button==okb) ende=1;
        else if(msg->button.button==cancelb) ende=-1;
        else if ( msg->button.button == addb ) {
	  if ( dirSet == false ) {
            str = NWC::Path::parentDir( WorkerInitialSettings::getInstance().getConfigBaseDir().c_str(), NULL );
	    dirSet = true;
	  } else {
	    str = dupstring("");
	  }
	  if ( frq->request( catalog.getLocale( 265 ),
			     str,
			     catalog.getLocale( 11 ),
			     catalog.getLocale( 8 ),
			     catalog.getLocale( 266 ) ) != 0 ) {
	    FileEntry *fe = frq->getFirstFE();
	    while ( fe != NULL ) {
	      int row = lv->addRow();
	      lv->setText( row, 0, fe->fullname );
	      lv->setPreColors( row, FieldListView::PRECOLOR_ONLYSELECT );
	      lv->redraw();
	      fe = frq->getNextFE();
	    }
	  }
	  _freesafe(str);
	} else if ( msg->button.button == delb ) {
	  for ( i = 0; i < lv->getElements();) {
	    if ( lv->getSelect( i ) == true ) {
	      lv->deleteRow( i );
	    } else i++;
	  }
	  lv->redraw();
	}
      }
      aguix->ReplyMessage(msg);
    }
    if(ende==1) {
      // Pruefen, ob Dateien existieren
      e = 0;
      for ( i = 0; i < lv->getElements(); i++ ) {
	if ( Datei::fileExists( lv->getText( 0, 0 ).c_str() ) == true ) e++;
      }
      if ( e < 3 ) {
	ende = 0;
	// Hinweis
	Requester *req = new Requester( aguix );
	req->request( catalog.getLocale( 124 ), catalog.getLocale( 267 ), catalog.getLocale( 11 ) );
	delete req;
      }
    }
  }
  if(ende==1) {
    PDatei *fh;
    unsigned char buffer[64];
    short int filedesc[64];

    for ( i = 0; i < 64; i++ ) {
      filedesc[i] = -1;
    }
    int run = 1, f1;
    fh = new PDatei();
    for ( f1 = 0; f1 < lv->getElements(); f1++ ) {
      if ( fh->open( lv->getText( f1, 0 ).c_str() ) == 0 ) {
	if ( fh->read( buffer, 64 ) == 64 ) {
	  if ( run == 1 ) {
	    for ( i = 0; i < 64; i++ ) {
	      if ( buffer[i] > 0 ) filedesc[i] = buffer[i];
	    }
	  } else {
	    for ( i = 0; i < 64; i++ ) {
	      if ( ( filedesc[i] > 0 ) && ( filedesc[i] != buffer[i] ) ) filedesc[i] = -1;
	    }
	  }
	  run++;
	}
	fh->close();
      }
    }
    delete fh;
    if ( run > 3 ) ft->setFiledesc( filedesc );
  }
  delete win;
  delete frq;
  return (ende==-1)?false:true;
}

bool WConfig::save()
{
    bool ret;
    char *textstr;
    std::string home = WorkerInitialSettings::getInstance().getConfigBaseDir();

    if ( home.length() < 1 ) return false;

    std::string str1 = home;
#ifdef USEOWNCONFIGFILES
    str1 = NWC::Path::join( str1, "wconfig2" );
#else
    str1 = NWC::Path::join( str1, "config" );
#endif

    if ( Datei::fileExistsExt( home.c_str() ) != Datei::D_FE_DIR ) {
        // no home dir, try to create one
        if ( worker_mkdir( home.c_str(), S_IRUSR | S_IXUSR | S_IWUSR ) != 0 ) {
            Requester *req = new Requester( worker->getAGUIX() );
            textstr = (char*)_allocsafe( strlen( catalog.getLocale( 127 ) ) + strlen( home.c_str() ) + 1 );
            sprintf( textstr, catalog.getLocale( 127 ), home.c_str() );
            req->request( catalog.getLocale( 347 ), textstr, catalog.getLocale( 11 ) );
            _freesafe( textstr );
            delete req;
        }
    }
    ret = saveas( str1 );
    
    currentConfigTime = time( NULL );
    return ret;
}

bool WConfig::saveas( const std::string &file )
{
  int id;
  char buf[3 * A_BYTESFORNUMBER( int ) + 3 ];
  std::string str1;
  int i;
  unsigned int j;
  std::list<LayoutSettings::layoutID_t>::const_iterator it1;
  std::string backupfile;

  backupfile = file;
  backupfile += "-workerbak";

  if ( Datei::lfileExistsExt( file.c_str() ) == Datei::D_FE_FILE ) {
      if ( worker_rename( file.c_str(), backupfile.c_str() ) != 0 ) {
          Requester *req = Worker::getRequester();
          char *textstr;
      
          textstr = (char*)_allocsafe( strlen( catalog.getLocale( 40 ) ) + strlen( file.c_str() ) + 1 );
          sprintf( textstr, catalog.getLocale( 40 ), file.c_str() );
          req->request( catalog.getLocale( 347 ), textstr, catalog.getLocale( 11 ) );
          _freesafe( textstr );
          return false;
      }
  }
  
  Datei *fh = new Datei();
  if ( fh->open( file.c_str(), "w" ) == 0 ) {
    sprintf( buf, "%d.%d.%d", WORKER_MAJOR, WORKER_MINOR, WORKER_PATCH );
    str1 = "workerconfig ";
    str1 += buf;
    str1 += ";";
    fh->putLine( str1.c_str() );
    fh->configOpenSection( "global" );
    fh->configPutPairString( "lang", lang );
    fh->configPutPairNum( "rows", rows );
    fh->configPutPairNum( "columns", columns );
    fh->configPutPairNum( "cachesize", cachesize );
    fh->configOpenSection( "listersets" );
    fh->configOpenSection( "left" );
    fh->configPutPairBool( "hbartop", hbar_top[0] );
    fh->configPutPairNum( "hbarheight", hbar_height[0] );
    fh->configPutPairBool( "vbarleft", vbar_left[0] );
    fh->configPutPairNum( "vbarwidth", vbar_width[0] );
    fh->configPutPairBool( "showheader", showHeader[0] );

    if ( getPathEntryOnTop( 0 ) == true ) {
        fh->configPutPairBool( "pathentryontop", getPathEntryOnTop( 0 ) );
    }

    fh->configOpenSection( "displaysets" );
    for ( j = 0; j < viscols[0].size(); j++ ) {
      switch ( viscols[0][j] ) {
        case WorkerTypes::LISTCOL_SIZE:
          fh->configPutInfo( "size", true );
          break;
        case WorkerTypes::LISTCOL_TYPE:
          fh->configPutInfo( "type", true );
          break;
        case WorkerTypes::LISTCOL_PERM:
          fh->configPutInfo( "permission", true );
          break;
        case WorkerTypes::LISTCOL_OWNER:
          fh->configPutInfo( "owner", true );
          break;
        case WorkerTypes::LISTCOL_DEST:
          fh->configPutInfo( "destination", true );
          break;
        case WorkerTypes::LISTCOL_MOD:
          fh->configPutInfo( "modtime", true );
          break;
        case WorkerTypes::LISTCOL_ACC:
          fh->configPutInfo( "acctime", true );
          break;
        case WorkerTypes::LISTCOL_CHANGE:
          fh->configPutInfo( "chgtime", true );
          break;
        case WorkerTypes::LISTCOL_INODE:
          fh->configPutInfo( "inode", true );
          break;
        case WorkerTypes::LISTCOL_NLINK:
          fh->configPutInfo( "nlink", true );
          break;
        case WorkerTypes::LISTCOL_BLOCKS:
          fh->configPutInfo( "blocks", true );
          break;
        case WorkerTypes::LISTCOL_SIZEH:
          fh->configPutInfo( "sizeh", true );
          break;
        case WorkerTypes::LISTCOL_EXTENSION:
          fh->configPutInfo( "extension", true );
          break;
        case WorkerTypes::LISTCOL_CUSTOM_ATTR:
          fh->configPutInfo( "customattribute", true );
          break;
        default:
          fh->configPutInfo( "name", true );
          break;
      }
    }
    fh->configCloseSection(); //displaysets
    fh->configCloseSection(); //left
    fh->configOpenSection( "right" );
    fh->configPutPairBool( "hbartop", hbar_top[1] );
    fh->configPutPairNum( "hbarheight", hbar_height[1] );
    fh->configPutPairBool( "vbarleft", vbar_left[1] );
    fh->configPutPairNum( "vbarwidth", vbar_width[1] );
    fh->configPutPairBool( "showheader", showHeader[1] );

    if ( getPathEntryOnTop( 1 ) == true ) {
        fh->configPutPairBool( "pathentryontop", getPathEntryOnTop( 1 ) );
    }

    fh->configOpenSection( "displaysets" );
    for ( j = 0; j < viscols[1].size(); j++ ) {
      switch ( viscols[1][j] ) {
        case WorkerTypes::LISTCOL_SIZE:
          fh->configPutInfo( "size", true );
          break;
        case WorkerTypes::LISTCOL_TYPE:
          fh->configPutInfo( "type", true );
          break;
        case WorkerTypes::LISTCOL_PERM:
          fh->configPutInfo( "permission", true );
          break;
        case WorkerTypes::LISTCOL_OWNER:
          fh->configPutInfo( "owner", true );
          break;
        case WorkerTypes::LISTCOL_DEST:
          fh->configPutInfo( "destination", true );
          break;
        case WorkerTypes::LISTCOL_MOD:
          fh->configPutInfo( "modtime", true );
          break;
        case WorkerTypes::LISTCOL_ACC:
          fh->configPutInfo( "acctime", true );
          break;
        case WorkerTypes::LISTCOL_CHANGE:
          fh->configPutInfo( "chgtime", true );
          break;
        case WorkerTypes::LISTCOL_INODE:
          fh->configPutInfo( "inode", true );
          break;
        case WorkerTypes::LISTCOL_NLINK:
          fh->configPutInfo( "nlink", true );
          break;
        case WorkerTypes::LISTCOL_BLOCKS:
          fh->configPutInfo( "blocks", true );
          break;
        case WorkerTypes::LISTCOL_SIZEH:
          fh->configPutInfo( "sizeh", true );
          break;
        case WorkerTypes::LISTCOL_EXTENSION:
          fh->configPutInfo( "extension", true );
          break;
        case WorkerTypes::LISTCOL_CUSTOM_ATTR:
          fh->configPutInfo( "customattribute", true );
          break;
        default:
          fh->configPutInfo( "name", true );
          break;
      }
    }
    fh->configCloseSection();//displaysets
    fh->configCloseSection();//right
    fh->configCloseSection();//listersets
    
    fh->configPutPairString( "terminal", terminalbin );
    if ( getTerminalReturnsEarly() ) {
        fh->configPutPairBool( "terminalreturnsearly", true );
    }

    if ( ownerstringtype == 1 ) fh->configPutPair( "ownerstyle", "style2" );
    else fh->configPutPair( "ownerstyle", "style1" );

    fh->configPutPairBool( "usestringfordirsize", showStringForDirSize );
    //fh->configPutPairString( "stringfordirsize", stringForDirSize );

    fh->configOpenSection( "timesets" );
    if ( date_format == 1 ) fh->configPutPair( "date", "style2" );
    else if ( date_format == 2 ) fh->configPutPair( "date", "style3" );
    else if ( date_format == -1 ) fh->configPutPair( "date", "userstyle" );
    else fh->configPutPair( "date", "style1" );
    fh->configPutPairString( "datestring", date_formatstring );
    fh->configPutPairBool( "datesubstitution", date_subst );
    if ( time_format == 1 ) fh->configPutPair( "time", "style2" );
    else if ( time_format == -1 ) fh->configPutPair( "time", "userstyle" );
    else fh->configPutPair( "time", "style1" );
    fh->configPutPairString( "timestring", time_formatstring );
    fh->configPutPairBool( "datebeforetime", date_before_time );
    fh->configCloseSection(); //timesets

    fh->configOpenSection( "palette" );
    i = 0;
    id = colors->initEnum();
    WC_Color *col = (WC_Color*)colors->getFirstElement( id );
    while ( col != NULL ) {
      sprintf( buf, "%d", i );
      str1 = buf;
      str1 += " = ";
      sprintf( buf, "%d", col->getRed() );
      str1 += buf;
      str1 += ",";
      sprintf( buf, "%d", col->getGreen() );
      str1 += buf;
      str1 += ",";
      sprintf( buf, "%d", col->getBlue() );
      str1 += buf;
      str1 += ";";
      fh->configPutInfo( str1.c_str(), false );
      col = (WC_Color*)colors->getNextElement( id );
      i++;
    }
    colors->closeEnum( id );
    fh->configCloseSection(); //palette

    fh->configOpenSection( "layout" );
    fh->configPutPairBool( "buttonsvertical", m_layout_conf.getButtonVert() );
    fh->configPutPairBool( "listviewsvertical", m_layout_conf.getListViewVert() );
    fh->configPutPairNum( "listviewweight", m_layout_conf.getListViewWeight() );
    fh->configPutPairBool( "weighttoactive", m_layout_conf.getWeightRelToActive() );
    for ( it1 = m_layout_conf.getOrders().begin();
          it1 != m_layout_conf.getOrders().end();
          it1++ ) {
      switch ( *it1 ) {
        case LayoutSettings::LO_STATEBAR:
          fh->configPutInfo( "statebar", true );
          break;
        case LayoutSettings::LO_CLOCKBAR:
          fh->configPutInfo( "clockbar", true );
          break;
        case LayoutSettings::LO_BUTTONS:
          fh->configPutInfo( "buttons", true );
          break;
        case LayoutSettings::LO_LISTVIEWS:
          fh->configPutInfo( "listviews", true );
          break;
        case LayoutSettings::LO_BLL:
          fh->configPutInfo( "bll", true );
          break;
        case LayoutSettings::LO_LBL:
          fh->configPutInfo( "lbl", true );
          break;
        case LayoutSettings::LO_LLB:
          fh->configPutInfo( "llb", true );
          break;
        case LayoutSettings::LO_BL:
          fh->configPutInfo( "bl", true );
          break;
        case LayoutSettings::LO_LB:
          fh->configPutInfo( "lb", true );
          break;
        default:
          break;
      }
    }
    fh->configCloseSection(); //layout

    fh->configOpenSection( "mouseconf" );
    fh->configPutPairNum( "selectbutton", mouseConf.select_button );
    fh->configPutPairNum( "activatebutton", mouseConf.activate_button );
    fh->configPutPairNum( "scrollbutton", mouseConf.scroll_button );
    
    fh->configOpenSection( "activatemod" );
    switch ( mouseConf.activate_mod ) {
        case ShiftMask:
            fh->configPutPair( "mod", "shift" );
            break;
        case ControlMask:
            fh->configPutPair( "mod", "control" );
            break;
        case Mod1Mask:
            fh->configPutPair( "mod", "mod1" );
            break;
        default:
            break;
    }
    fh->configCloseSection(); //activatemod

    fh->configOpenSection( "scrollmod" );
    switch ( mouseConf.scroll_mod ) {
        case ShiftMask:
            fh->configPutPair( "mod", "shift" );
            break;
        case ControlMask:
            fh->configPutPair( "mod", "control" );
            break;
        case Mod1Mask:
            fh->configPutPair( "mod", "mod1" );
            break;
        default:
            break;
    }
    fh->configCloseSection(); //scrollmod

    fh->configOpenSection( "contextmod" );
    switch ( mouseConf.context_mod ) {
        case ShiftMask:
            fh->configPutPair( "mod", "shift" );
            break;
        case ControlMask:
            fh->configPutPair( "mod", "control" );
            break;
        case Mod1Mask:
            fh->configPutPair( "mod", "mod1" );
            break;
        default:
            break;
    }
    fh->configCloseSection(); //contextmod

    switch ( mouseConf.select_method ) {
      case MOUSECONF_ALT_MODE:
	fh->configPutPair( "selectmethod", "alternative" );
	break;
      default:
	fh->configPutPair( "selectmethod", "normal" );
	break;
    }

    if ( mouseConf.context_menu_with_delayed_activate ) {
        fh->configPutPairBool( "delayedcontextmenu", true );
    }

    fh->configCloseSection(); //mouseconf

    fh->configPutPairBool( "saveworkerstateonexit", m_save_worker_state_on_exit );

    fh->configOpenSection( "volumemanager" );
    fh->configPutPairString( "mountcommand", getVMMountCommand().c_str() );
    fh->configPutPairString( "unmountcommand", getVMUnmountCommand().c_str() );
    fh->configPutPairString( "fstabfile", getVMFStabFile().c_str() );
    fh->configPutPairString( "mtabfile", getVMMtabFile().c_str() );
    fh->configPutPairString( "partfile", getVMPartitionFile().c_str() );
    fh->configPutPairBool( "requestaction", getVMRequestAction() );
    fh->configPutPairString( "ejectcommand", getVMEjectCommand().c_str() );
    fh->configPutPairString( "closetraycommand", getVMCloseTrayCommand().c_str() );

    if ( getVMPreferredUdisksVersion() == 2 ) {
        fh->configPutPairNum( "prefer_udisks_version", getVMPreferredUdisksVersion() );
    }
    
    fh->configCloseSection(); //volumemanager

    if ( m_use_string_compare_mode == StringComparator::STRING_COMPARE_VERSION ) {
        fh->configPutPairBool( "useversionstringcompare", true );
    } else if ( m_use_string_compare_mode == StringComparator::STRING_COMPARE_NOCASE ) {
        fh->configPutPair( "usestringcomparemode", "strcasecmp" );
    } else {
        fh->configPutPairBool( "useversionstringcompare", false );
    }

    if ( m_use_extended_regex ) {
        fh->configPutPairBool( "useextendedregex", m_use_extended_regex );
    }

#if 0
    if ( ! m_apply_window_dialog_type ) {
        fh->configPutPairBool( "applywindowdialogtype", m_apply_window_dialog_type );
    }
#endif

    if ( ! getDisableBGCheckPrefix().empty() ) {
        fh->configPutPairString("disablebgcheckprefix", getDisableBGCheckPrefix().c_str() );
    }

    fh->configCloseSection();//global

    fh->configOpenSection( "colors" );

    fh->configOpenSection( "labelcolors" );

    std::map<std::string, WConfig::ColorDef::label_colors_t>::const_iterator label_it1;
    const std::map<std::string, WConfig::ColorDef::label_colors_t> &labelcolors = _color_defs.getLabelColors();

    for ( label_it1 = labelcolors.begin();
          label_it1 != labelcolors.end();
          ++label_it1 ) {
        fh->configOpenSection( "color" );
        fh->configPutPairString( "name", label_it1->first.c_str() );
        fh->configPutPairNum( "normal", label_it1->second.normal_fg, label_it1->second.normal_bg );
        fh->configPutPairNum( "active", label_it1->second.active_fg, label_it1->second.active_bg );

        if ( label_it1->second.only_exact_path ) {
            fh->configPutPairBool( "onlyexactpath", label_it1->second.only_exact_path );
        }

        fh->configCloseSection(); //labelcolor
    }

    fh->configCloseSection(); //labelcolors

    auto fl = m_facedb.getListOfFaces();
    FaceDB default_faces;
    bool non_default_face_found = false;

    fl.sort();

    for ( auto &face_name : fl ) {
        Face f = m_facedb.getFace( face_name );
        Face default_f = default_faces.getFace( face_name );

        if ( f.getName() != default_f.getName() ||
             f.getColor() != default_f.getColor() ) {
            non_default_face_found = true;
            break;
        }
    }

    if ( non_default_face_found ) {
        fh->configOpenSection( "faces" );

        for ( auto &face_name : fl ) {
            Face f = m_facedb.getFace( face_name );
            Face default_f = default_faces.getFace( face_name );

            if ( f.getName() != default_f.getName() ||
                 f.getColor() != default_f.getColor() ) {
                fh->configOpenSection( "face" );
                fh->configPutPairString( "name", f.getName().c_str() );
                fh->configPutPairNum( "color", f.getColor() );
                fh->configCloseSection(); //face
            }
        }

        fh->configCloseSection(); //faces
    }

    fh->configCloseSection(); //colors

    fh->configOpenSection( "startup" );
    fh->configPutPairString( "left", dir[0] );
    fh->configPutPairString( "right", dir[1] );

    switch ( m_restore_tabs_mode ) {
        case RESTORE_TABS_ALWAYS:
            fh->configPutPair( "restore_tabs_mode", "always" );
            break;
        case RESTORE_TABS_ASK:
            fh->configPutPair( "restore_tabs_mode", "ask" );
            break;
        default:
            break;
    }

    switch ( m_store_tabs_mode ) {
        case STORE_TABS_ALWAYS:
            fh->configPutPair( "store_tabs_mode", "always" );
            break;
        case STORE_TABS_AS_EXIT_STATE:
            fh->configPutPair( "store_tabs_mode", "as_exit_state" );
            break;
        case STORE_TABS_ASK:
            fh->configPutPair( "store_tabs_mode", "ask" );
            break;
        default:
            break;
    }

    fh->configCloseSection(); //startup

    fh->configOpenSection( "fonts" );
    fh->configPutPairString( "globalfont", getFontName( FONT_X11_GLOBAL ).c_str() );
    fh->configPutPairString( "buttonfont", getFontName( FONT_X11_BUTTONS ).c_str() );
    fh->configPutPairString( "leftfont", getFontName( FONT_X11_LEFT ).c_str() );
    fh->configPutPairString( "rightfont", getFontName( FONT_X11_RIGHT ).c_str() );
    fh->configPutPairString( "textviewfont", getFontName( FONT_X11_TEXTVIEW ).c_str() );
    fh->configPutPairString( "statebarfont", getFontName( FONT_X11_STATEBAR ).c_str() );

    if ( getFontName( FONT_X11_TEXTVIEW_ALT ) != DEFAULT_X11_FONT_FIXED ) {
        fh->configPutPairString( "textviewaltfont", getFontName( FONT_X11_TEXTVIEW_ALT ).c_str() );
    }

    fh->configCloseSection(); //fonts

#ifdef HAVE_XFT
    fh->configOpenSection( "xftfonts" );
    fh->configPutPairString( "globalfont", getFontName( FONT_XFT_GLOBAL ).c_str() );
    fh->configPutPairString( "buttonfont", getFontName( FONT_XFT_BUTTONS ).c_str() );
    fh->configPutPairString( "leftfont", getFontName( FONT_XFT_LEFT ).c_str() );
    fh->configPutPairString( "rightfont", getFontName( FONT_XFT_RIGHT ).c_str() );
    fh->configPutPairString( "textviewfont", getFontName( FONT_XFT_TEXTVIEW ).c_str() );
    fh->configPutPairString( "statebarfont", getFontName( FONT_XFT_STATEBAR ).c_str() );

    if ( getFontName( FONT_XFT_TEXTVIEW_ALT ) != DEFAULT_XFT_FONT_FIXED ) {
        fh->configPutPairString( "textviewaltfont", getFontName( FONT_XFT_TEXTVIEW_ALT ).c_str() );
    }

    fh->configCloseSection(); //xftfonts
#endif

    fh->configOpenSection( "clockbarsets" );
    switch(clockbar_mode) {
      case CLOCKBAR_MODE_TIME:
        fh->configPutPair( "modus", "time" );
        break;
      case CLOCKBAR_MODE_VERSION:
        fh->configPutPair( "modus", "version" );
        break;
      case CLOCKBAR_MODE_EXTERN:
        fh->configPutPair( "modus", "extern" );
        break;
      case CLOCKBAR_MODE_CUSTOM:
        fh->configPutPair( "modus", "custom" );
        break;
      default:
        fh->configPutPair( "modus", "timespace" );
        break;
    }
    fh->configPutPairNum( "updatetime", clockbar_updatetime );
    fh->configPutPairString( "program", clockbar_command );
    if ( getClockbarHints() != true ) {
        fh->configPutPairBool( "showhints", getClockbarHints() );
    }
    if ( ! m_clockbar_custom[0].empty() ) {
        fh->configPutPairString( "custom", m_clockbar_custom[0] );
    }
    if ( ! m_clockbar_custom[1].empty() ) {
        fh->configPutPairString( "customwithhint", m_clockbar_custom[1] );
    }
    fh->configCloseSection(); //clockbarsets
    
    fh->configOpenSection( "pathjumpallowdirs" );
    for ( std::list< std::string >::const_iterator it2 = m_pathjump_allow_dirs.begin();
          it2 != m_pathjump_allow_dirs.end();
          it2++ ) {
        fh->configPutString( it2->c_str(), true );
    }
    fh->configCloseSection(); //pathjump_allow_dirs

    if ( getPathJumpStoreFilesAlways() == true ) {
        fh->configOpenSection( "pathjumpsets" );
        fh->configPutPairBool( "storefilesalways", getPathJumpStoreFilesAlways() );
        fh->configCloseSection(); //pathjumpsets
    }

    fh->configOpenSection( "paths" );
    i = 0;
    id = paths->initEnum();
    WCPath *p1 = (WCPath*)paths->getFirstElement( id );
    while ( p1 != NULL ) {
      if ( p1->getCheck() != false ) {
        fh->configOpenSection( "path" );
        fh->configPutPairNum( "position", i );
        p1->save( fh );
        fh->configCloseSection(); //path
      }
      p1 = (WCPath*)paths->getNextElement( id );
      i++;
    }
    paths->closeEnum( id );
    fh->configCloseSection(); //paths

    fh->configOpenSection( "hotkeys" );
    id = hotkeys->initEnum();
    WCHotkey *h1 = (WCHotkey*)hotkeys->getFirstElement( id );
    while(h1!=NULL) {
      fh->configOpenSection( "hotkey" );
      h1->save( fh );
      fh->configCloseSection(); //hotkey
      h1 = (WCHotkey*)hotkeys->getNextElement( id );
    }
    hotkeys->closeEnum( id );
    fh->configCloseSection(); //hotkeys

    fh->configOpenSection( "buttons" );
    i = 0;
    id = buttons->initEnum();
    WCButton *b1 = (WCButton*)buttons->getFirstElement( id );
    while ( b1 != NULL ) {
      if ( b1->getCheck() != false ) {
        fh->configOpenSection( "button" );
        fh->configPutPairNum( "position", i );
        b1->save( fh );
        fh->configCloseSection(); //button
      }
      b1 = (WCButton*)buttons->getNextElement( id );
      i++;
    }
    buttons->closeEnum( id );
    fh->configCloseSection(); //buttons

    fh->configOpenSection( "filetypes" );
    id = filetypes->initEnum();
    WCFiletype *f1 = (WCFiletype*)filetypes->getFirstElement( id );
    while ( f1 != NULL ) {
      fh->configOpenSection( "filetype" );
      f1->save( fh );
      fh->configCloseSection(); //filetype
      f1 = (WCFiletype*)filetypes->getNextElement( id );
    }
    filetypes->closeEnum( id );

    fh->configOpenSection( "ignoredirs" );

    bool has_pattern_dcd = false;
    for ( const auto &d : m_dont_check_dirs ) {
        if ( ! d.is_pattern ) {
            fh->configPutString( d.dir.c_str(), true );
        } else {
            has_pattern_dcd = true;
        }
    }
    fh->configCloseSection(); //ignoredirs

    // to stay backward compatible in case no pattern filters are used
    if ( has_pattern_dcd ) {
        fh->configOpenSection( "ignoredirs2" );

        for ( const auto &d : m_dont_check_dirs ) {
            if (  d.is_pattern ) {
                fh->configOpenSection( "ignoredir" );
                fh->configPutPairString( "pattern", d.dir.c_str() );
                fh->configCloseSection(); //ignoredir
            }
        }

        fh->configCloseSection(); //ignoredirs2
    }

    fh->configPutPairBool( "dontcheckvirtual", dontcheckvirtual );

    fh->configCloseSection(); //filetypes

    if ( ! m_directory_presets.empty() ) {
        fh->configOpenSection( "directorypresets" );

        for ( auto &preset : m_directory_presets ) {
            fh->configOpenSection( "directorypreset" );

            fh->configPutPairString( "path", preset.first.c_str() );

            fh->configPutPair( "hiddenfiles" , ( preset.second.show_hidden == true ) ? "show" : "hide" );

            switch ( preset.second.sortmode & 0xff ) {
                case SORT_SIZE:
                    fh->configPutPair( "sortby", "size" );
                    break;
                case SORT_ACCTIME:
                    fh->configPutPair( "sortby", "acctime" );
                    break;
                case SORT_MODTIME:
                    fh->configPutPair( "sortby", "modtime" );
                    break;
                case SORT_CHGTIME:
                    fh->configPutPair( "sortby", "chgtime" );
                    break;
                case SORT_TYPE:
                    fh->configPutPair( "sortby", "type" );
                    break;
                case SORT_OWNER:
                    fh->configPutPair( "sortby", "owner" );
                    break;
                case SORT_INODE:
                    fh->configPutPair( "sortby", "inode" );
                    break;
                case SORT_NLINK:
                    fh->configPutPair( "sortby", "nlink" );
                    break;
                case SORT_PERMISSION:
                    fh->configPutPair( "sortby", "permission" );
                    break;
                case SORT_EXTENSION:
                    fh->configPutPair( "sortby", "extension" );
                    break;
                case SORT_CUSTOM_ATTRIBUTE:
                    fh->configPutPair( "sortby", "customattribute" );
                    break;
                default:
                    fh->configPutPair( "sortby", "name" );
                    break;
            }
            if ( ( preset.second.sortmode & SORT_REVERSE ) != 0 ) fh->configPutPair( "sortflag", "reverse" );
            if ( ( preset.second.sortmode & SORT_DIRLAST ) != 0 ) fh->configPutPair( "sortflag", "dirlast" );
            else if ( ( preset.second.sortmode & SORT_DIRMIXED ) != 0 ) fh->configPutPair( "sortflag", "dirmixed" );

            for ( auto &filter : preset.second.filters ) {
                fh->configOpenSection( "filter" );
                filter.save( fh );
                fh->configCloseSection(); //filter
            }

            fh->configCloseSection(); // directorypreset
        }
        fh->configCloseSection(); // directorypresets
    }

    m_kvp_pool->save( fh );

    fh->close();

    if ( fh->errors() != 0 ) {
      Requester req( worker->getAGUIX() );
      char *textstr;
      
      textstr = (char*)_allocsafe( strlen( catalog.getLocale( 40 ) ) + strlen( file.c_str() ) + 1 );
      sprintf( textstr, catalog.getLocale( 40 ), file.c_str() );
      req.request( catalog.getLocale( 347 ), textstr, catalog.getLocale( 11 ) );
      _freesafe( textstr );
      delete fh;
      return false;
    }
    delete fh;
  } else {
    Requester *req=new Requester(worker->getAGUIX());
    char *textstr;
    textstr=(char*)_allocsafe(strlen(catalog.getLocale(40))+strlen(file.c_str())+1);
    sprintf(textstr,catalog.getLocale(40),file.c_str());
    req->request(catalog.getLocale(347),textstr,catalog.getLocale(11));
    _freesafe(textstr);
    delete req;
    delete fh;
    return false;
  }
  return true;
}

bool WConfig::load()
{
    bool ret = false;

    std::string home = WorkerInitialSettings::getInstance().getConfigBaseDir();

    if ( home.length() < 1 ) return false;

    std::string str1 = home;
#ifdef USEOWNCONFIGFILES
    str1 = NWC::Path::join( str1, "wconfig2" );
#else
    str1 = NWC::Path::join( str1, "config" );
#endif
  
    if ( Datei::lfileExistsExt( home.c_str() )== Datei::D_FE_NOFILE ) {
        const char *buttonstr;
        const char *textstr;
        Requester *req;
    
        buttonstr = catalog.getLocale( 11 );
        textstr = "There is no Worker configuration directory.|Worker will continue and use an internal configuration!";
        req = new Requester( worker->getAGUIX() );
        req->request( catalog.getLocale( 124 ), textstr, buttonstr );
        delete req;
    } else {
        ret = loadfrom( str1 );
        
        currentConfigTime = time( NULL );
    }
    return ret;
}

bool WConfig::loadfrom( const std::string &file )
{
  Datei *fh;
  char buf[5];
  FILE *fp;
  char *tstr;
  
  fh = new Datei();
  if ( fh->open( file.c_str(), "r" ) == 0 ) {
    fh->getString( buf, 4 );
    fh->close();
    delete fh;
    if ( strcmp( buf, "FORM" ) == 0 ) {
        // 2er binary config
        const char *buttonstr;
        const char *textstr;
    
        buttonstr = catalog.getLocale( 11 );
        textstr = "Your configuration is from an old Worker version.|To load it and convert it into the new format,|use Worker version 2.x.";
        Requester req( worker->getAGUIX() );
        req.request( catalog.getLocale( 124 ), textstr, buttonstr );

        return false;
    } else {
      // looks like new textconfig
      lconfig = this;
      fp = worker_fopen( file.c_str(), "r" );
      if ( fp != NULL ) {
        yyrestart( fp );
        if ( yymyparse() != 0 ) {
          // there was an error but after the requester I will
          // continue with the partly read config
          tstr = (char*)_allocsafe( strlen( catalog.getLocale( 539 ) ) +
                                    A_BYTESFORNUMBER(int) +
                                    strlen( lconfig_error ) + 1 );
          sprintf( tstr, catalog.getLocale( 539 ), lconfig_linenr + 1,
                   lconfig_error );
          Worker::getRequester()->request( catalog.getLocale( 347 ),
                                           tstr,
                                           catalog.getLocale( 11 ) );
          _freesafe( tstr );
        }
        applyColorList( colors );
        initFixTypes();
        worker_fclose( fp );
      }
    }
  }
  return false;
}

void WConfig::initFixTypes()
{
  WCFiletype *ft;
  // Pruefen, welche feste Type vorhanden sind (per Bitmaske)
  int id;

  notyettype = NULL;
  unknowntype = NULL;
  voidtype = NULL;
  dirtype = NULL;

  id = filetypes->initEnum();
  ft = (WCFiletype*)filetypes->getFirstElement( id );
  while ( ft != NULL ) {
    switch ( ft->getinternID() ) {
      case NOTYETTYPE:
        if ( notyettype != NULL ) {
          // there is already one special type, reset this
          ft->setinternID( NORMALTYPE );
        } else {
          notyettype = ft;
        }
        break;
      case UNKNOWNTYPE:
        if ( unknowntype != NULL ) {
          // there is already one special type, reset this
          ft->setinternID( NORMALTYPE );
        } else {
          unknowntype = ft;
        }
        break;
      case VOIDTYPE:
        if ( voidtype != NULL ) {
          // there is already one special type, reset this
          ft->setinternID( NORMALTYPE );
        } else {
          voidtype = ft;
        }
        break;
      case DIRTYPE:
        if ( dirtype != NULL ) {
          // there is already one special type, reset this
          ft->setinternID( NORMALTYPE );
        } else {
          dirtype = ft;
        }
        break;
    }
    ft = (WCFiletype*)filetypes->getNextElement( id );
  }
  filetypes->closeEnum( id );
  
  if ( notyettype == NULL ) {
    // NotYet voreinstellen
    debugmsg("Notyet erstellen\n"); //TODO: Diese Zeile entfernen
    ft=new WCFiletype();
    ft->setName(catalog.getLocale(344));
    ft->setinternID(NOTYETTYPE);
    // Reicht vorerst, denn irgendwelche Patterns oder so sind (im jetztigen Stadium des
    // Programms) nicht sinnvoll
    notyettype=ft;
    filetypes->addElementAt(NOTYETTYPE-1,ft);
  }

  if (  unknowntype == NULL ) {
    // Unknown voreinstellen
    debugmsg("Unknown erstellen\n"); //TODO: Diese Zeile entfernen
    ft=new WCFiletype();
    ft->setName(catalog.getLocale(345));
    ft->setinternID(UNKNOWNTYPE);
    unknowntype = ft;
    filetypes->addElementAt(UNKNOWNTYPE-1,ft);
  }
  
  if ( voidtype == NULL ) {
    // Void voreinstellen (der wird nie im Lister angezeigt)
    debugmsg("void erstellen\n"); //TODO: Diese Zeile entfernen
    ft=new WCFiletype();
    ft->setName(catalog.getLocale(346));
    ft->setinternID(VOIDTYPE);
    voidtype = ft;
    filetypes->addElementAt(VOIDTYPE-1,ft);
  }
  
  if ( dirtype == NULL ) {
    // Dir voreinstellen
    debugmsg("dir erstellen\n"); //TODO: Diese Zeile entfernen
    ft=new WCFiletype();
    ft->setName(catalog.getLocale(109));
    ft->setinternID(DIRTYPE);
    dirtype=ft;
    filetypes->addElementAt(DIRTYPE-1,ft);
  }
}

WCFiletype *WConfig::getnotyettype()
{
  return notyettype;
}

WCFiletype *WConfig::getdirtype()
{
  return dirtype;
}

WCFiletype *WConfig::getvoidtype()
{
  return voidtype;
}

WCFiletype *WConfig::getunknowntype()
{
  return unknowntype;
}

void WConfig::applyLanguage()
{
  if((strcmp(lang,"builtin")==0)||(strlen(lang)<1)) catalog.resetLanguage();
  else catalog.loadLanguage(lang);
}

void WConfig::setOwnerstringtype(int nv)
{
  ownerstringtype=nv;
  if(ownerstringtype<0) ownerstringtype=0;
  else if(ownerstringtype>1) ownerstringtype=1;
}

int WConfig::getOwnerstringtype()
{
  return ownerstringtype;
}

bool WConfig::isCorrectTerminalBin(const char *tstr)
{
  if ( ! tstr ) return false;
  const char *pos;
  if(strlen(tstr)<1) return true;
  pos=strstr(tstr,"%s");
  if(pos!=NULL) return true;
  return false;
}

const char *WConfig::getTerminalStr()
{
  if(strlen(terminalbin)<1) return TERMINAL_BIN;
  else if(isCorrectTerminalBin(terminalbin)==false) return TERMINAL_BIN;
  return terminalbin;
}

void WConfig::setClockbarMode(WConfig::clockbar_mode_t nm)
{
  clockbar_mode=nm;
}

WConfig::clockbar_mode_t WConfig::getClockbarMode()
{
  return clockbar_mode;
}

void WConfig::setClockbarUpdatetime(int nv)
{
  clockbar_updatetime=nv;
  if(clockbar_updatetime<1) clockbar_updatetime=1;
}

int WConfig::getClockbarUpdatetime()
{
  return clockbar_updatetime;
}

void WConfig::setClockbarHints( bool nv )
{
    m_clockbar_hints = nv;
}

bool WConfig::getClockbarHints()
{
    return m_clockbar_hints;
}

void WConfig::setShowStringForDirSize(bool nv)
{
  showStringForDirSize=nv;
}

bool WConfig::getShowStringForDirSize()
{
  return showStringForDirSize;
}

void WConfig::setStringForDirSize(const char *nv)
{
  _freesafe(stringForDirSize);
  if(nv!=NULL) stringForDirSize=dupstring(nv);
  else stringForDirSize=dupstring("<DIR>");
  stringForDirSizeLen=strlen(stringForDirSize);
}

const char *WConfig::getStringForDirSize()
{
  return stringForDirSize;
}

void WConfig::setClockbarCommand( const std::string &s )
{
    clockbar_command = s;
}

const std::string &WConfig::getClockbarCommand() const
{
  return clockbar_command;
}

void WConfig::setClockbarCustom( const std::string &s, uint8_t variant )
{
    if ( variant < 2 ) {
        m_clockbar_custom[ variant ] = s;
    }
}

const std::string &WConfig::getClockbarCustom( uint8_t variant ) const
{
    if ( variant == 1 ) {
        return m_clockbar_custom[ 1 ];
    }
    return m_clockbar_custom[ 0 ];
}

void WConfig::setDontCheckDirs( const std::list< WConfigTypes::dont_check_dir > &ndcd )
{
    m_dont_check_dirs = ndcd;
}

const std::list< WConfigTypes::dont_check_dir > &WConfig::getDontCheckDirs() const
{
  return m_dont_check_dirs;
}

void WConfig::setDontCheckVirtual( bool nv )
{
  dontcheckvirtual = nv;
}

bool WConfig::getDontCheckVirtual() const
{
  return dontcheckvirtual;
}

int WConfig::getStringForDirSizeLen()
{
  return stringForDirSizeLen;
}

int WConfig::cfg_export( const char *filename )
{
  AWindow *win;
  AGUIX *aguix = worker->getAGUIX();
  int ende;
  AGMessage *msg;
  ChooseButton *cb[3];
  Button *b[3], *b2[2];
  WConfig *exportconfig;
  std::string str1;
  Requester *req;
  
  win = new AWindow( aguix, 10, 10, 10, 10, catalog.getLocale( 398 ), AWindow::AWINDOW_DIALOG );
  win->create();

  AContainer *ac1 = win->setContainer( new AContainer( win, 1, 3 ), true );
  ac1->setMinSpace( 5 );
  ac1->setMaxSpace( 5 );
  ac1->setBorderWidth( 5 );

  win->addMultiLineText( catalog.getLocale( 399 ), *ac1, 0, 0, NULL, NULL );

  AContainer *ac1_2 = ac1->add( new AContainer( win, 2, 3 ), 0, 1 );
  ac1_2->setMinSpace( 5 );
  ac1_2->setMaxSpace( 5 );
  ac1_2->setBorderWidth( 0 );

  cb[0] = (ChooseButton*)ac1_2->add( new ChooseButton( aguix, 0, 0, false, "", LABEL_RIGHT, 0 ),
                                     0, 0, AContainer::CO_FIX );
  b[0] = (Button*)ac1_2->add( new Button( aguix, 0, 0, catalog.getLocale( 401 ), 0 ),
                              1, 0, AContainer::CO_FIX );

  cb[1] = (ChooseButton*)ac1_2->add( new ChooseButton( aguix, 0, 0, false, "", LABEL_RIGHT, 0 ),
                                     0, 1, AContainer::CO_FIX );
  b[1] = (Button*)ac1_2->add( new Button( aguix, 0, 0, catalog.getLocale( 402 ), 0 ),
                              1, 1, AContainer::CO_FIX );

  cb[2] = (ChooseButton*)ac1_2->add( new ChooseButton( aguix, 0, 0, false, "", LABEL_RIGHT, 0 ),
                                     0, 2, AContainer::CO_FIX );
  b[2] = (Button*)ac1_2->add( new Button( aguix, 0, 0, catalog.getLocale( 403 ), 0 ),
                              1, 2, AContainer::CO_FIX );
  
  AContainer *ac1_1 = ac1->add( new AContainer( win, 2, 1 ), 0, 2 );
  ac1_1->setMinSpace( 5 );
  ac1_1->setMaxSpace( -1 );
  ac1_1->setBorderWidth( 0 );
  b2[0] =(Button*)ac1_1->add( new Button( aguix,
                                          0,
                                          0,
                                          catalog.getLocale( 398 ),
                                          0 ), 0, 0, AContainer::CO_FIX );
  b2[1] = (Button*)ac1_1->add( new Button( aguix,
                                           0,
                                           0,
                                           catalog.getLocale( 8 ),
                                           0 ), 1, 0, AContainer::CO_FIX );
  win->setDoTabCycling( true );
  win->contMaximize( true, true );
  win->show();
  
  exportconfig = duplicate();
  
  req = new Requester( aguix );
  
  ende = 0;
  while ( ende == 0 ) {
    msg = aguix->WaitMessage( win );
    if ( msg != NULL ) {
      if ( msg->type == AG_CLOSEWINDOW ) {
        if ( msg->closewindow.window == win->getWindow() )
          ende = -1;
      } else if ( msg->type == AG_BUTTONCLICKED ) {
        if ( msg->button.button == b2[0] ) {
          // Okay
          ende = 1;
        } else if ( msg->button.button == b2[1] ) {
          // Cancel
          ende = -1;
        } else if ( msg->button.button == b[0] ) {
          exportconfig->changeButtons();
        } else if ( msg->button.button == b[1] ) {
          exportconfig->changeHotkeys();
        } else if ( msg->button.button == b[2] ) {
          exportconfig->changeTypes( true );
        }
      }

      aguix->ReplyMessage( msg );
    }
    if ( ende == 1 ) {
      // try to export
      // in case of failure keep this window so we do this
      // inside the loop
      // export the exportconfig according to choosebuttons

      if ( cb[0]->getState() == true ||
           cb[1]->getState() == true ||
           cb[2]->getState() == true ) {
        // something to export
        // when export failed set ende back to 0

        if ( exportconfig->export2file( cb[0]->getState(),
                                        cb[1]->getState(),
                                        cb[2]->getState(),
                                        filename ) != 0 ) {
          ende = 0;
        }
      } else {
        req->request( catalog.getLocale( 124 ), catalog.getLocale( 407 ),
                      catalog.getLocale( 11 ) );
        ende = 0;
      }
    }
  }
  
  delete win;
  
  delete exportconfig;
  delete req;

  return ( ende == -1 ) ? 1 : 0;
}

int WConfig::export2file( bool export_buttons,
                          bool export_hotkeys,
                          bool export_types,
                          const char *filename )
{
  Datei fh;
  Datei::d_fe_t e;
  int erg, ret;
  Requester req( worker->getAGUIX() );
  char *tstr;
  std::string s1;
  int id;
  WCButton *b1;
  WCHotkey *h1;
  WCFiletype *f1;
  char buf[3 * A_BYTESFORNUMBER( int ) + 3 ];
  std::string str1;
  int i;
  
  ret = 0;
  
  if ( filename == NULL ) return 1;

  e = Datei::fileExistsExt( filename );
  if ( e != Datei::D_FE_NOFILE ) {
    // something exists with this name!
    if ( e == Datei::D_FE_DIR ) {
      // dir -> show request and exit
      tstr = (char*)_allocsafe( strlen( catalog.getLocale( 408 ) ) + strlen( filename ) + 1 );
      sprintf( tstr, catalog.getLocale( 408 ), filename );
      req.request( catalog.getLocale( 124 ), tstr, catalog.getLocale( 11 ) );
      _freesafe( tstr );
      return 1;
    }
    // ask for overwriting this file
    // otherwise return
    tstr = (char*)_allocsafe( strlen( catalog.getLocale( 409 ) ) + strlen( filename ) + 1 );
    sprintf( tstr, catalog.getLocale( 409 ), filename );
    s1 = catalog.getLocale( 11 );
    s1 += "|";
    s1 += catalog.getLocale( 8 );
    erg = req.request( catalog.getLocale( 123 ), tstr, s1.c_str() );
    _freesafe( tstr );
    
    if ( erg == 1 )
      return 1;
    
  }

  if ( fh.open( filename, "w" ) == 0 ) {
    sprintf( buf, "%d.%d.%d", WORKER_MAJOR, WORKER_MINOR, WORKER_PATCH );
    str1 = "workerconfig ";
    str1 += buf;
    str1 += ";";
    fh.putLine( str1.c_str() );

    if ( export_buttons == true ) {
      fh.configOpenSection( "buttons" );
      i = 0;
      id = buttons->initEnum();
      b1 = (WCButton*)buttons->getFirstElement( id );
      while ( b1 != NULL ) {
        if ( b1->getCheck() != false ) {
          fh.configOpenSection( "button" );
          fh.configPutPairNum( "position", i );
          b1->save( &fh );
          fh.configCloseSection(); //button
        }
        b1 = (WCButton*)buttons->getNextElement( id );
        i++;
      }
      buttons->closeEnum( id );

      fh.configCloseSection(); //buttons
    }
    
    if ( export_hotkeys == true ) {
      fh.configOpenSection( "hotkeys" );
      id = hotkeys->initEnum();
      h1 = (WCHotkey*)hotkeys->getFirstElement( id );
      while ( h1 != NULL ) {
        fh.configOpenSection( "hotkey" );
        h1->save( &fh );
        fh.configCloseSection(); //hotkey
        h1 = (WCHotkey*)hotkeys->getNextElement( id );
      }
      hotkeys->closeEnum( id );
      fh.configCloseSection(); //hotkeys
    }
    
    if ( export_types == true ) {
      fh.configOpenSection( "filetypes" );
      id = filetypes->initEnum();
      f1 = (WCFiletype*)filetypes->getFirstElement( id );
      while ( f1 != NULL ) {
        fh.configOpenSection( "filetype" );
        f1->save( &fh );
        fh.configCloseSection(); //filetype
        f1 = (WCFiletype*)filetypes->getNextElement( id );
      }
      filetypes->closeEnum( id );
      fh.configCloseSection(); //filetypes
    }
    
    fh.close();

    if ( fh.errors() == 0 ) {
      tstr = (char*)_allocsafe( strlen( catalog.getLocale( 410 ) ) + strlen( filename ) + 1 );
      sprintf( tstr, catalog.getLocale( 410 ), filename );
      req.request( catalog.getLocale( 124 ), tstr, catalog.getLocale( 11 ) );
      _freesafe( tstr );
    } else {
      tstr = (char*)_allocsafe( strlen( catalog.getLocale( 359 ) ) + strlen( filename ) + 1 );
      sprintf( tstr, catalog.getLocale( 359 ), filename );
      req.request( catalog.getLocale( 124 ), tstr, catalog.getLocale( 11 ) );
      _freesafe( tstr );
      ret = 1;
    }
  } else {
    tstr = (char*)_allocsafe( strlen( catalog.getLocale( 411 ) ) + strlen( filename ) + 1 );
    sprintf( tstr, catalog.getLocale( 411 ), filename );
    req.request( catalog.getLocale( 124 ), tstr, catalog.getLocale( 11 ) );
    _freesafe( tstr );
    ret = 1;
  }

  return ret;
}

/*
 * loads the file in a temp. config and calls configureForImport with it
 */
int WConfig::loadImportConfig( const char *filename,
                               bool &import_buttons,
                               bool &import_hotkeys,
                               bool &import_filetypes,
                               const std::string &info_text,
                               WConfig **return_config )
{
  AGUIX *aguix = worker->getAGUIX();
  WConfig *importconfig = NULL;
  Requester req( aguix );
  Datei fh;
  char buf[5];
  int erg = 0;
  List *bl;
  char *tstr;
  FILE *fp;

  // first try to load the config
  if ( Datei::fileExistsExt( filename ) == Datei::D_FE_FILE ) {
    if ( fh.open( filename, "r" ) == 0 ) {
      importconfig = duplicate();
      
      fh.getString( buf, 4 );
      if ( strcmp( buf, "FORM" ) == 0 ) {
          req.request( catalog.getLocale( 124 ),
                       "Loading old binary configs not supported, use a Worker version 2.x",
                       catalog.getLocale( 11 ) );
      } else {
        lconfig = importconfig;
        bl = new List();
        lconfig->setButtons( bl );
        lconfig->setHotkeys( bl );
        lconfig->setFiletypes( bl );
        delete bl;
        fp = worker_fopen( filename, "r" );
        if ( fp != NULL ) {
          yyrestart( fp );
          if ( yymyparse() != 0 ) {
            // there was an error but after the requester I will
            // continue with the partly read config
            tstr = (char*)_allocsafe( strlen( catalog.getLocale( 539 ) ) +
                                      A_BYTESFORNUMBER(int) +
                                      strlen( lconfig_error ) + 1 );
            sprintf( tstr, catalog.getLocale( 539 ), lconfig_linenr + 1,
                     lconfig_error );
            Worker::getRequester()->request( catalog.getLocale( 347 ),
                                             tstr,
                                             catalog.getLocale( 11 ) );
            _freesafe( tstr );
          } else {
            // config load successful
            // now let the user decide...
            erg = importconfig->configureForImport( 1,
                                                    import_buttons,
                                                    import_hotkeys,
                                                    import_filetypes,
                                                    info_text );
          }
          worker_fclose( fp );
        } else {
          // can't open for reading
          tstr = (char*)_allocsafe( strlen( catalog.getLocale( 281 ) ) + strlen( filename ) + 1 );
          sprintf( tstr, catalog.getLocale( 281 ), filename );
          req.request( catalog.getLocale( 124 ),
                       tstr,
                       catalog.getLocale( 11 ) );
          _freesafe( tstr );
          erg = 1;
        }
      }
      fh.close();
    } else {
      // can't open for reading
      tstr = (char*)_allocsafe( strlen( catalog.getLocale( 281 ) ) + strlen( filename ) + 1 );
      sprintf( tstr, catalog.getLocale( 281 ), filename );
      req.request( catalog.getLocale( 124 ),
                   tstr,
                   catalog.getLocale( 11 ) );
      _freesafe( tstr );
      erg = 1;
    }
  } else {
    // not a file
    tstr = (char*)_allocsafe( strlen( catalog.getLocale( 412 ) ) + strlen( filename ) + 1 );
    sprintf( tstr, catalog.getLocale( 412 ), filename );
    req.request( catalog.getLocale( 124 ),
                 tstr,
                 catalog.getLocale( 11 ) );
    _freesafe( tstr );
    erg = 1;
  }

  if ( return_config != NULL )
    *return_config = importconfig;
  else
    delete importconfig;

  return erg;
}

/*
 * show the users a similar window to export
 * user can choose which part (buttons/hotkeys/filetypes) he want to import
 * and can configure them before import
 */
int WConfig::configureForImport( int nrb,
                                 bool &import_buttons,
                                 bool &import_hotkeys,
                                 bool &import_filetypes,
                                 const std::string &info_text )
{
  AWindow *win;
  AGUIX *aguix = Worker::getAGUIX();
  int ende;
  AGMessage *msg;
  ChooseButton *cb[3];
  Button *b[3],*b2[2];
  Requester req( aguix );
  int nr_of_b, nr_of_h, nr_of_f;
  char *tstr;
  bool apply_b = false, apply_h = false, apply_f = false;
  List *l1;
  WCButton *b1;
  int id, i, banksize;

  if ( nrb < 1 ) {
    nr_of_b = 0;
  } else {
    l1 = getButtons();
    nr_of_b = 0;
    i = 0;
    id = l1->initEnum();
    b1 = (WCButton*)l1->getFirstElement( id );
    while ( b1 != NULL ) {
      if ( b1->getCheck() == true ) {
        nr_of_b = i + 1;
      }
      b1 = (WCButton*)l1->getNextElement( id );
      i++;
    }
    l1->closeEnum( id );
    banksize = ( getRows() * getColumns() * 2 );
    nr_of_b += ( banksize - ( nr_of_b % banksize ) ) % banksize;
    nr_of_b /= banksize;
  }
  
  nr_of_h = getHotkeys()->size();
  nr_of_f = getFiletypes()->size();
  
  if ( ( nr_of_b == 0 ) && ( nr_of_h == 0 ) && ( nr_of_f == 0 ) ) {
    req.request( catalog.getLocale( 124 ), catalog.getLocale( 418 ), catalog.getLocale( 11 ) );
    return 1;
  }
  
  tstr = (char*)_allocsafe( info_text.length() + ( 3 * A_BYTESFORNUMBER( int ) ) + 1 );
  sprintf( tstr, info_text.c_str(), nr_of_b, nr_of_h, nr_of_f );
  req.request( catalog.getLocale( 124 ),
               tstr,
               catalog.getLocale( 11 ) );
  _freesafe( tstr );

  win = new AWindow( aguix, 10, 10, 10, 10, catalog.getLocale( 397 ), AWindow::AWINDOW_DIALOG );
  win->create();

  AContainer *ac1 = win->setContainer( new AContainer( win, 1, 3 ), true );
  ac1->setMinSpace( 5 );
  ac1->setMaxSpace( 5 );
  ac1->setBorderWidth( 5 );

  win->addMultiLineText( catalog.getLocale( 416 ), *ac1, 0, 0, NULL, NULL );

  int cont_h = 0, cont_pos = 0;
  if ( nr_of_b > 0 )
    cont_h++;
  if ( nr_of_h > 0 )
    cont_h++;
  if ( nr_of_f > 0 )
    cont_h++;

  AContainer *ac1_2 = ac1->add( new AContainer( win, 2, cont_h ), 0, 1 );
  ac1_2->setMinSpace( 5 );
  ac1_2->setMaxSpace( 5 );
  ac1_2->setBorderWidth( 0 );

  if ( nr_of_b > 0 ) {
    cb[0] = (ChooseButton*)ac1_2->add( new ChooseButton( aguix, 0, 0, true, "", LABEL_RIGHT, 0 ),
                                       0, cont_pos, AContainer::CO_FIX );
    b[0] = (Button*)ac1_2->add( new Button( aguix, 0, 0, catalog.getLocale( 540 ), 0 ),
                                1, cont_pos, AContainer::CO_FIX );
    cont_pos++;
  } else {
    cb[0] = NULL;
    b[0] = NULL;
  }

  if ( nr_of_h > 0 ) {
    cb[1] = (ChooseButton*)ac1_2->add( new ChooseButton( aguix, 0, 0, true, "", LABEL_RIGHT, 0 ),
                                       0, cont_pos, AContainer::CO_FIX );
    b[1] = (Button*)ac1_2->add( new Button( aguix, 0, 0, catalog.getLocale( 541 ), 0 ),
                                1, cont_pos, AContainer::CO_FIX );
    cont_pos++;
  } else {
    cb[1] = NULL;
    b[1] = NULL;
  }

  if ( nr_of_f > 0 ) {
    cb[2] = (ChooseButton*)ac1_2->add( new ChooseButton( aguix, 0, 0, true, "", LABEL_RIGHT, 0 ),
                                       0, cont_pos, AContainer::CO_FIX );
    b[2] = (Button*)ac1_2->add( new Button( aguix, 0, 0, catalog.getLocale( 542 ), 0 ),
                                1, cont_pos, AContainer::CO_FIX );
    cont_pos++;
  } else {
    cb[2] = NULL;
    b[2] = NULL;
  }
  
  AContainer *ac1_1 = ac1->add( new AContainer( win, 2, 1 ), 0, 2 );
  ac1_1->setMinSpace( 5 );
  ac1_1->setMaxSpace( -1 );
  ac1_1->setBorderWidth( 0 );
  b2[0] =(Button*)ac1_1->add( new Button( aguix,
                                          0,
                                          0,
                                          catalog.getLocale( 397 ),
                                          0 ), 0, 0, AContainer::CO_FIX );
  b2[1] = (Button*)ac1_1->add( new Button( aguix,
                                           0,
                                           0,
                                           catalog.getLocale( 8 ),
                                           0 ), 1, 0, AContainer::CO_FIX );

  win->setDoTabCycling( true );
  win->contMaximize( true, true );
  win->show();
  
  ende = 0;
  while ( ende == 0 ) {
    msg = aguix->WaitMessage( win );
    if ( msg != NULL ) {
      if ( msg->type == AG_CLOSEWINDOW ) {
        if ( msg->closewindow.window == win->getWindow() )
          ende = -1;
      } else if ( msg->type == AG_BUTTONCLICKED ) {
        if ( msg->button.button == b2[0] ) {
          // Okay
          ende = 1;
        } else if ( msg->button.button == b2[1] ) {
          // Cancel
          ende = -1;
        } else if ( ( msg->button.button == b[0] ) && ( b[0] != NULL ) ) {
          changeButtons();
        } else if ( ( msg->button.button == b[1] ) && ( b[1] != NULL ) )  {
          changeHotkeys();
        } else if ( ( msg->button.button == b[2] ) && ( b[2] != NULL ) )  {
          changeTypes( true );
        }
      } else if ( msg->type == AG_STRINGGADGET_DEACTIVATE ) {
      }

      aguix->ReplyMessage( msg );
    }
    if ( ende == 1 ) {
      // now try to import
      // in case of failure keep this window so we do this
      // inside the loop
      
      if ( cb[0] != NULL ) {
        apply_b = cb[0]->getState();
      } else apply_b = false;

      if ( cb[1] != NULL ) {
        apply_h = cb[1]->getState();
      } else apply_h = false;

      if ( cb[2] != NULL ) {
        apply_f = cb[2]->getState();
      } else apply_f = false;

      if ( apply_b == false &&
           apply_h == false &&
           apply_f == false ) {
        req.request( catalog.getLocale( 124 ), catalog.getLocale( 417 ),
                      catalog.getLocale( 11 ) );
        ende = 0;
      }
    }
  }
  
  delete win;
  
  if ( ende == 1 ) {
    import_buttons = apply_b;
    import_hotkeys = apply_h;
    import_filetypes = apply_f;
  }

  return ( ende == -1 ) ? 1 : 0;
}

void WConfig::setDateFormat( int nv )
{
  date_format = nv;
  if ( date_format < -1 ) date_format = 0;
}

int WConfig::getDateFormat()
{
  return date_format;
}

void WConfig::setDateFormatString( const char *nv )
{
  _freesafe( date_formatstring );
  if ( nv == NULL ) {
    date_formatstring = dupstring( DEFAULT_DATE_STRING );
  } else {
    date_formatstring = dupstring( nv );
  }
}

const char *WConfig::getDateFormatString()
{
  return date_formatstring;
}

void WConfig::setDateSubst( bool nv )
{
  date_subst = nv;
}

bool WConfig::getDateSubst()
{
  return date_subst;
}

void WConfig::setTimeFormat( int nv )
{
  time_format = nv;
  if ( time_format < -1 ) time_format = 0;
}

int WConfig::getTimeFormat()
{
  return time_format;
}

void WConfig::setTimeFormatString( const char *nv )
{
  _freesafe( time_formatstring );
  if ( nv == NULL ) {
    time_formatstring = dupstring( DEFAULT_TIME_STRING );
  } else {
    time_formatstring = dupstring( nv );
  }
}

const char *WConfig::getTimeFormatString()
{
  return time_formatstring;
}

void WConfig::setDateBeforeTime( bool nv )
{
  date_before_time = nv;
}

bool WConfig::getDateBeforeTime()
{
  return date_before_time;
}

int WConfig::writeDateToString( std::string &str, struct tm *tptr )
{
    const char *tformat, *dformat;
    int i, nr_of_predates, nr_of_pretimes;
    time_t now;
    struct tm *timeptr, todaytime, yesterdaytime, tomorrowtime, curtime;
    bool istoday = false, isyesterday = false, istomorrow = false;
    char date_buf[256], time_buf[256];
    struct tm temptm;
  
    if ( tptr == NULL ) return 0;
  
    curtime = *tptr;

    now = time( NULL );
    timeptr = localtime_r( &now, &temptm );
    todaytime = *timeptr;

    now -= 24*60*60;  // this is yesterday
    timeptr = localtime_r( &now, &temptm );
    yesterdaytime = *timeptr;

    now += 2*24*60*60; // this is tomorrow
    timeptr = localtime_r( &now, &temptm );
    tomorrowtime = *timeptr;
  
    if ( curtime.tm_mday == todaytime.tm_mday &&
         curtime.tm_mon == todaytime.tm_mon &&
         curtime.tm_year == todaytime.tm_year ) {
        istoday = true;
    } else if ( curtime.tm_mday == yesterdaytime.tm_mday &&
                curtime.tm_mon == yesterdaytime.tm_mon &&
                curtime.tm_year == yesterdaytime.tm_year ) {
        isyesterday = true;
    } else if ( curtime.tm_mday == tomorrowtime.tm_mday &&
                curtime.tm_mon == tomorrowtime.tm_mon &&
                curtime.tm_year == tomorrowtime.tm_year ) {
        istomorrow = true;
    }

    nr_of_predates = sizeof( predefined_dates ) / sizeof( predefined_dates[0] );
    nr_of_pretimes = sizeof( predefined_times ) / sizeof( predefined_times[0] );

    if ( date_format == -1 ) {
        dformat = date_formatstring;
    } else {
        i = 0;
        if ( date_format >= 0 && date_format < nr_of_predates ) {
            i = date_format;
        }
        dformat = predefined_dates[i];
    }

    if ( strftime( date_buf, 255, dformat, &curtime ) == 0 ) {
        date_buf[0] = '\0';
    }

    int time_characters = UTF8::getNumberOfCharacters( date_buf );
    int max_time_characters = time_characters;
    int yesterday_chars = 0, today_chars = 0, tomorrow_chars = 0;

    if ( date_subst == true ) {
        yesterday_chars = UTF8::getNumberOfCharacters( catalog.getLocale( 436 ) );
        if ( yesterday_chars > max_time_characters ) max_time_characters = yesterday_chars;

        today_chars = UTF8::getNumberOfCharacters( catalog.getLocale( 437 ) );
        if ( today_chars > max_time_characters ) max_time_characters = today_chars;

        tomorrow_chars = UTF8::getNumberOfCharacters( catalog.getLocale( 438 ) );
        if ( tomorrow_chars > max_time_characters ) max_time_characters = tomorrow_chars;
    }

    if ( time_format == -1 ) {
        tformat = time_formatstring;
    } else {
        i = 0;
        if ( time_format >= 0 && time_format < nr_of_pretimes ) {
            i = time_format;
        }
        tformat = predefined_times[i];
    }

    if ( strftime( time_buf, 255, tformat, &curtime ) == 0 ) {
        time_buf[0] = '\0';
    }
  
    for ( i = 0; i < 2; i++ ) {
        if ( ( date_before_time == true && i == 0 ) ||
             ( date_before_time == false && i == 1 ) ) {
            if ( date_subst == true && istoday == true ) {
                str += catalog.getLocale( 437 );

                str += std::string( max_time_characters - today_chars, ' ' );
            } else if ( date_subst == true && isyesterday == true ) {
                str += catalog.getLocale( 436 );

                str += std::string( max_time_characters - yesterday_chars, ' ' );
            } else if ( date_subst == true && istomorrow == true ) {
                str += catalog.getLocale( 438 );

                str += std::string( max_time_characters - tomorrow_chars, ' ' );
            } else {
                str += date_buf;
            }
        } else {
            str += time_buf;
        }
        if ( i == 0 ) str += ' ';
    }

    return 1;
}

/*
 * just grabs a key without checking for other uses
 *
 * returns:
 *   0 no error
 *  -1 error
 */
int WConfig::grabKey( const char *title, const char *text, KeySym *return_key, unsigned int *return_mod )
{
  AGUIX *aguix = worker->getAGUIX();
  int w, h;
  int returnvalue = -1;
  
  if ( ( title == NULL ) || ( text == NULL ) || ( return_key == NULL ) || ( return_mod == NULL ) ) return -1;

  w = 10;
  h = 10;
  AWindow *win = new AWindow( aguix, 10, 10, w, h, title, AWindow::AWINDOW_DIALOG );
  win->create();
  win->addTextFromString( text, 5, 5, 5, NULL, NULL, NULL );
  win->maximizeX();
  win->maximizeY();
  win->centerScreen();
  w = win->getWidth();
  h = win->getHeight();
  win->setMaxSize( w, h );
  win->setMinSize( w, h );
  win->show();
  AGMessage *msg;
  while ( ( msg = aguix->GetMessage( NULL ) ) != NULL ) aguix->ReplyMessage( msg );
  int ende = 0;
  
  while ( ende == 0 ) {
    msg = aguix->WaitMessage( win );
    if ( msg != NULL ) {
      if ( msg->type == AG_CLOSEWINDOW ) {
        if ( msg->closewindow.window == win->getWindow() ) ende = -1;
      } else if ( msg->type == AG_KEYPRESSED ) {
        if ( AGUIX::isModifier( msg->key.key ) == false ) {
          *return_key = msg->key.key;
          *return_mod = KEYSTATEMASK( msg->key.keystate );
          returnvalue = 0;
          ende = 1;
        }
      }
      aguix->ReplyMessage( msg );
    }
  }
  delete win;

  if ( ende < 0 ) returnvalue = -1;  
  return returnvalue;
}

/*
 * getDoubleShortkey
 * Returnvalue:
 * -1 Cancel, null in return_dk
 * 0 Okay, no collision, DoubleShortkey in return_dk
 * 1 Okay, collision with ignore_?, null in return_dk
 * 2 Okay, collision with some other, DoubleShortkey in return_dk
 */
int WConfig::getDoubleShortkey( bool doublek,
                                const WCButton *ignore_b,
                                const WCHotkey *ignore_h,
                                const WCPath *ignore_p,
                                WCDoubleShortkey **return_dk)
{
  WCDoubleShortkey *tsk = NULL;
  AGUIX *aguix = worker->getAGUIX();
  WCButton *b1;
  WCPath *p1;
  WCHotkey *h1;
  char *textstr, *buttonstr;
  Requester *req = new Requester( aguix );
  int erg;
  int returnvalue = -1;
  KeySym key1 = 0, key2 = 0;
  unsigned int mod1 = 0, mod2 = 0;
  
  tsk = new WCDoubleShortkey();
  int ende = 0;
  while ( ende == 0 ) {
    if ( doublek == true ) {
      erg = grabKey( catalog.getLocale( 66 ), catalog.getLocale( 455 ), &key1, &mod1 );
      if ( erg == 0 ) {
        erg = grabKey( catalog.getLocale( 66 ), catalog.getLocale( 456 ), &key2, &mod2 );
      }
      if ( erg == 0 ) {
      } else {
        // user aborted
        ende = -1;
      }
    } else {
      erg = grabKey( catalog.getLocale( 66 ), catalog.getLocale( 66 ), &key1, &mod1 );
      if ( erg != 0 ) ende = -1;
    }
    if ( ende == 0 ) {
      tsk->setType( doublek == true ? WCDoubleShortkey::WCDS_DOUBLE : WCDoubleShortkey::WCDS_NORMAL );
      tsk->setKeySym( key1, 0 );
      tsk->setMod( mod1, 0 );
      if ( doublek == true ) {
        tsk->setKeySym( key2, 1 );
        tsk->setMod( mod2, 1 );
      }
      // search for other reference
      if ( findDoubleShortkey( tsk, getButtons(), getPaths(), getHotkeys(), &b1, &p1, &h1 ) != 0 ) {
        if ( b1 != NULL ) {
          if ( b1 == ignore_b ) {
            returnvalue = 1;
            ende = 1;
          } else {
            textstr = (char*)_allocsafe( strlen( catalog.getLocale( 42 ) ) + strlen( b1->getText() ) + 1 );
            sprintf( textstr, catalog.getLocale( 42 ), b1->getText() );
            buttonstr = (char*)_allocsafe( strlen( catalog.getLocale( 41 ) ) + 1 +
                                           strlen( catalog.getLocale( 11 ) ) + 1 +
                                           strlen( catalog.getLocale( 8 ) ) + 1 );
            sprintf( buttonstr, "%s|%s|%s", catalog.getLocale( 41 ),
                                            catalog.getLocale( 11 ),
                                            catalog.getLocale( 8 ) );
            erg = req->request( catalog.getLocale( 125 ), textstr, buttonstr );
            _freesafe( textstr );
            _freesafe( buttonstr );
            if ( erg == 2 ) ende = -1;
            else if ( erg == 1 ) {
              returnvalue = 2;
              ende = 1;
            }
          }
        } else if ( p1 != NULL ) {
          if ( p1 == ignore_p ) {
            returnvalue = 1;
            ende = 1;
          } else {
            textstr = (char*)_allocsafe( strlen( catalog.getLocale( 63 ) ) + strlen( p1->getName() ) + 1 );
            sprintf( textstr, catalog.getLocale( 63 ), p1->getName() );
            buttonstr = (char*)_allocsafe( strlen( catalog.getLocale( 41 ) ) + 1 +
                                           strlen( catalog.getLocale( 11 ) ) + 1 +
                                           strlen( catalog.getLocale( 8 ) ) + 1 );
            sprintf( buttonstr, "%s|%s|%s", catalog.getLocale( 41 ),
                                            catalog.getLocale( 11 ),
                                            catalog.getLocale( 8 ) );
            erg = req->request( catalog.getLocale( 125 ), textstr, buttonstr );
            _freesafe( textstr );
            _freesafe( buttonstr );
            if ( erg == 2 ) ende = -1;
            else if ( erg == 1 ) {
              returnvalue = 2;
              ende = 1;
            }
          }
        } else if ( h1 != NULL ) {
          if ( h1 == ignore_h ) {
            returnvalue = 1;
            ende = 1;
          } else {
            textstr = (char*)_allocsafe( strlen( catalog.getLocale( 65 ) ) + strlen( h1->getName() ) + 1 );
            sprintf( textstr, catalog.getLocale( 65 ), h1->getName() );
            buttonstr = (char*)_allocsafe( strlen( catalog.getLocale( 41 ) ) + 1 +
                                           strlen( catalog.getLocale( 11 ) ) + 1 +
                                           strlen( catalog.getLocale( 8 ) ) + 1 );
            sprintf( buttonstr, "%s|%s|%s", catalog.getLocale( 41 ),
                                            catalog.getLocale( 11 ),
                                            catalog.getLocale( 8 ) );
            erg = req->request( catalog.getLocale( 125 ), textstr, buttonstr );
            _freesafe( textstr );
            _freesafe( buttonstr );
            if ( erg == 2 ) ende = -1;
            else if ( erg == 1 ) {
              returnvalue = 2;
              ende = 1;
            }
          }
        }
      } else {
        returnvalue = 0;
        ende = 1;
      }
    }
  }
  delete req;

  if ( ende < 0 ) returnvalue = -1;  
  if( ( ( returnvalue == 2 ) ||
        ( returnvalue == 0 ) ) &&
      ( return_dk != NULL ) ) {
    *return_dk = tsk;
  } else {
    if ( return_dk != NULL )
      *return_dk = NULL;
    if ( tsk != NULL )
      delete tsk;
  }
  return returnvalue;
}

int WConfig::findDoubleShortkey( WCDoubleShortkey *dk,
                                 List *button_list,
                                 List *path_list,
                                 List *hotkey_list,
                                 WCButton **return_button,
                                 WCPath **return_path,
                                 WCHotkey **return_hotkey )
{
  int id;
  WCHotkey *h1 = NULL;
  WCButton *b1 = NULL;
  WCPath *p1 = NULL;

  if ( hotkey_list != NULL ) {
    // search for a hotkey
    id = hotkey_list->initEnum();
    h1 = (WCHotkey*)hotkey_list->getFirstElement( id );
    while ( h1 != NULL ) {
      if ( h1->conflictKey( dk ) == true )
        break;
      h1 = (WCHotkey*)hotkey_list->getNextElement( id );
    }
    hotkey_list->closeEnum( id );
    if ( h1 != NULL ) {
      *return_button = NULL;
      *return_path = NULL;
      *return_hotkey = h1;
      return 1;
    }
  }
  
  if ( path_list != NULL ) {
    // search for a path
    id = path_list->initEnum();
    p1 = (WCPath*)path_list->getFirstElement( id );
    while ( p1 != NULL ) {
      if ( p1->conflictKey( dk ) == true )
        break;
      p1 = (WCPath*)path_list->getNextElement( id );
    }
    path_list->closeEnum( id );
    if ( p1 != NULL ) {
      *return_button = NULL;
      *return_path = p1;
      *return_hotkey = NULL;
      return 2;
    }
  }

  if ( button_list != NULL ) {
    // search for a button
    id = button_list->initEnum();
    b1 = (WCButton*)button_list->getFirstElement( id );
    while ( b1 != NULL ) {
      if ( b1->conflictKey( dk ) == true )
        break;
      b1 = (WCButton*)button_list->getNextElement( id );
    }
    button_list->closeEnum( id );
    if ( b1 != NULL ) {
      *return_button = b1;
      *return_path = NULL;
      *return_hotkey = NULL;
      return 3;
    }
  }
  
  *return_button = NULL;
  *return_path = NULL;
  *return_hotkey = NULL;
  return 0;
}

bool WConfig::checkForNewerConfig()
{
  if ( difftime( getFileConfigMod(), currentConfigTime ) > 0 ) return true;
  return false;
}

time_t WConfig::getFileConfigMod()
{
  worker_struct_stat buf;
  std::string str1;

  str1 = WorkerInitialSettings::getInstance().getConfigBaseDir();
#ifdef USEOWNCONFIGFILES
  str1 = NWC::Path::join( str1, "wconfig2" );
#else
  str1 = NWC::Path::join( str1, "config" );
#endif
  if ( worker_stat( str1.c_str(), &buf ) == 0 ) {
    return buf.st_mtime;
  }
  return 0;
}

void WConfig::setShowHeader( int side, bool nv )
{
  if ( ( side < 0 ) || ( side > 1 ) ) return;
  showHeader[side] = nv;
}

bool WConfig::getShowHeader( int side ) const
{
  return showHeader[ ( side == 1 ) ? 1 : 0 ];
}

void WConfig::setPathEntryOnTop( int side, bool nv )
{
    if ( side < 0 || side > 1 ) return;
    m_path_entry_on_top[side] = nv;
}

bool WConfig::getPathEntryOnTop( int side ) const
{
    return m_path_entry_on_top[ ( side == 1 ) ? 1 : 0 ];
}

void WConfig::setLayoutOrders( const std::list< LayoutSettings::layoutID_t > &nl )
{
    m_layout_conf.setOrders( nl );
}

const std::list<LayoutSettings::layoutID_t> &WConfig::getLayoutOrders() const
{
    return m_layout_conf.getOrders();
}

void WConfig::setLayoutButtonVert( bool nv )
{
    m_layout_conf.setButtonVert( nv );
}

bool WConfig::getLayoutButtonVert() const
{
    return m_layout_conf.getButtonVert();
}

void WConfig::setLayoutListviewVert( bool nv )
{
    m_layout_conf.setListViewVert( nv );
}

bool WConfig::getLayoutListviewVert() const
{
    return m_layout_conf.getListViewVert();
}

void WConfig::clearLayoutOrders()
{
    m_layout_conf.clearOrders();
}

void WConfig::layoutAddEntry( LayoutSettings::layoutID_t nv )
{
    m_layout_conf.pushBackOrder( nv );
}

void WConfig::setLayoutListViewWeight( int nv )
{
    m_layout_conf.setListViewWeight( nv );
}

int WConfig::getLayoutListViewWeight() const
{
    return m_layout_conf.getListViewWeight();
}

void WConfig::setLayoutWeightRelToActive( bool nv )
{
    m_layout_conf.setWeightRelToActive( nv );
}

bool WConfig::getLayoutWeightRelToActive() const
{
    return m_layout_conf.getWeightRelToActive();
}

std::unique_ptr< FlatTypeList > WConfig::getFlatTypeList() const
{
    return std::make_unique< FlatTypeList >( FlatTypeList( filetypes, "" ) );
}

void WConfig::setMouseSelectButton( int nv )
{
  switch ( nv ) {
    case 2:
    case 3:
      mouseConf.select_button = nv;
      break;
    default:
      mouseConf.select_button = 1;
  }
}

void WConfig::setMouseActivateButton( int nv )
{
  switch ( nv ) {
    case 2:
    case 3:
      mouseConf.activate_button = nv;
      break;
    default:
      mouseConf.activate_button = 1;
  }
}
 
void WConfig::setMouseScrollButton( int nv )
{
  switch ( nv ) {
    case 2:
    case 3:
      mouseConf.scroll_button = nv;
      break;
    default:
      mouseConf.scroll_button = 1;
  }
}

void WConfig::setMouseContextButton( int nv )
{
  switch ( nv ) {
    case 2:
    case 3:
      mouseConf.context_button = nv;
      break;
    default:
      mouseConf.context_button = 1;
  }
}

void WConfig::setMouseSelectMethod( mouseconf_method_t nv )
{
  mouseConf.select_method = nv;
}

int WConfig::getMouseSelectButton() const
{
  return mouseConf.select_button;
}

int WConfig::getMouseActivateButton() const
{
  return mouseConf.activate_button;
}

int WConfig::getMouseScrollButton() const
{
  return mouseConf.scroll_button;
}

int WConfig::getMouseContextButton() const
{
  return mouseConf.context_button;
}

WConfig::mouseconf_method_t WConfig::getMouseSelectMethod() const
{
  return mouseConf.select_method;
}

void WConfig::setMouseActivateMod( int nv )
{
    switch( nv ) {
        case ShiftMask:
        case ControlMask:
        case Mod1Mask:
            mouseConf.activate_mod = nv;
            break;
        default:
            mouseConf.activate_mod = 0;
            break;
    }
}

void WConfig::setMouseScrollMod( int nv )
{
    switch( nv ) {
        case ShiftMask:
        case ControlMask:
        case Mod1Mask:
            mouseConf.scroll_mod = nv;
            break;
        default:
            mouseConf.scroll_mod = 0;
            break;
    }
}

void WConfig::setMouseContextMod( int nv )
{
    switch( nv ) {
        case ShiftMask:
        case ControlMask:
        case Mod1Mask:
            mouseConf.context_mod = nv;
            break;
        default:
            mouseConf.context_mod = 0;
            break;
    }
}

int WConfig::getMouseActivateMod() const
{
    return mouseConf.activate_mod;
}

int WConfig::getMouseScrollMod() const
{
    return mouseConf.scroll_mod;
}

int WConfig::getMouseContextMod() const
{
    return mouseConf.context_mod;
}

void WConfig::setMouseContextMenuWithDelayedActivate( bool nv )
{
    mouseConf.context_menu_with_delayed_activate = nv;
}

bool WConfig::getMouseContextMenuWithDelayedActivate() const
{
    return mouseConf.context_menu_with_delayed_activate;
}

typedef enum { NONE, LANG, PALETTE, FONTCONF, MOUSECONF, STARTCONF, LISTCONF, VIEWCONF, TIMECONF,
               COLORCONF, BUTTON, PATH, FILETYPE, HOTKEY, CLOCKCONF, DCDCONF, UICOLORS, BUTTONGRPCONF,
               CACHECONF, OWNERCONF, TERMCONF, DIRSIZECONF, LAYOUTCONF, IMEXPORT, MAINUICONF,
               EXPERTUICONF, GENERALCONF, BOOKMARKCOLORS, VOLMANCONF, PATHJUMPALLOWCONF,
               DIRECTORYPRESETSCONF, KVPPANELCONF } type_t;

typedef struct {
  std::string key;
  std::string base_key;
  type_t type;
  WConfigPanel *subwin;
  int level;
} lv_key_type_t;

class MyWConfigPanelCallBack : public WConfigPanelCallBack
{
public:
  MyWConfigPanelCallBack( lv_key_type_t *lv_lookup_table, int table_size ) : _lv_lookup_table( lv_lookup_table ),
                                                                             _table_size( table_size )
  {
  }
  ~MyWConfigPanelCallBack()
  {
  }
  void setColors( List *colors )
  {
    for ( int i = 0; i < _table_size; i++ ) {
      if ( _lv_lookup_table[i].subwin != NULL ) {
        _lv_lookup_table[i].subwin->setColors( colors );
      }
    }
  }
  void setRows( int rows )
  {
    for ( int i = 0; i < _table_size; i++ ) {
      if ( _lv_lookup_table[i].subwin != NULL ) {
        _lv_lookup_table[i].subwin->setRows( rows );
      }
    }
  }
  void setColumns( int columns )
  {
    for ( int i = 0; i < _table_size; i++ ) {
      if ( _lv_lookup_table[i].subwin != NULL ) {
        _lv_lookup_table[i].subwin->setColumns( columns );
      }
    }
  }

    void setFaceDB( const FaceDB &faces )
    {
        for ( int i = 0; i < _table_size; i++ ) {
            if ( _lv_lookup_table[i].subwin != NULL ) {
                _lv_lookup_table[i].subwin->setFaceDB( faces );
            }
        }
    }

  int addButtons( List *buttons, add_action_t action )
  {
    int erg = 0;
    for ( int i = 0; i < _table_size && erg == 0; i++ ) {
      if ( _lv_lookup_table[i].subwin != NULL ) {
        erg = _lv_lookup_table[i].subwin->addButtons( buttons, action );
      }
    }
    return erg;
  }
  int addHotkeys( List *hotkeys, add_action_t action )
  {
    int erg = 0;
    for ( int i = 0; i < _table_size && erg == 0; i++ ) {
      if ( _lv_lookup_table[i].subwin != NULL ) {
        erg = _lv_lookup_table[i].subwin->addHotkeys( hotkeys, action );
      }
    }
    return erg;
  }
  int addFiletypes( List *filetypes, add_action_t action )
  {
    int erg = 0;
    for ( int i = 0; i < _table_size && erg == 0; i++ ) {
      if ( _lv_lookup_table[i].subwin != NULL ) {
        erg = _lv_lookup_table[i].subwin->addFiletypes( filetypes, action );
      }
    }
    return erg;
  }
private:
  lv_key_type_t *_lv_lookup_table;
  int _table_size;
};

static void recreatePanel( int i, lv_key_type_t *lv_lookup_table, int table_size,
                           AWindow *win,
                           WConfig *tempconfig,
                           WConfig *button_path_hotkey_conf,
                           MyWConfigPanelCallBack *panelcb )
{
  if ( lv_lookup_table[i].subwin != NULL )
    delete lv_lookup_table[i].subwin;
  
  switch ( lv_lookup_table[i].type ) {
    case LANG:
      lv_lookup_table[i].subwin = new LangPanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case PALETTE:
      lv_lookup_table[i].subwin = new PalettePanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case FONTCONF:
      lv_lookup_table[i].subwin = new FontPanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case MOUSECONF:
      lv_lookup_table[i].subwin = new MousePanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case STARTCONF:
      lv_lookup_table[i].subwin = new StartPanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case CLOCKCONF:
      lv_lookup_table[i].subwin = new ClockPanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case LISTCONF:
      lv_lookup_table[i].subwin = new ListerPanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case VIEWCONF:
      lv_lookup_table[i].subwin = new ListViewPanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case TIMECONF:
      lv_lookup_table[i].subwin = new TimePanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case UICOLORS:
      lv_lookup_table[i].subwin = new ColorPanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case COLORCONF:
      lv_lookup_table[i].subwin = new ColorConfPanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case BUTTON:
      lv_lookup_table[i].subwin = new ButtonPanel( *win, *button_path_hotkey_conf );
      lv_lookup_table[i].subwin->create();
      break;
    case BUTTONGRPCONF:
      lv_lookup_table[i].subwin = new ButtonGrpConfPanel( *win, *button_path_hotkey_conf );
      lv_lookup_table[i].subwin->create();
      break;
    case PATH:
      lv_lookup_table[i].subwin = new PathPanel( *win, *button_path_hotkey_conf );
      lv_lookup_table[i].subwin->create();
      break;
    case FILETYPE:
      lv_lookup_table[i].subwin = new FiletypePanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case HOTKEY:
      lv_lookup_table[i].subwin = new HotkeyPanel( *win, *button_path_hotkey_conf );
      lv_lookup_table[i].subwin->create();
      break;
    case DCDCONF:
      lv_lookup_table[i].subwin = new DCDPanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case CACHECONF:
      lv_lookup_table[i].subwin = new CacheSizePanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case OWNERCONF:
      lv_lookup_table[i].subwin = new OwnerConfPanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case TERMCONF:
      lv_lookup_table[i].subwin = new TermConfPanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case DIRSIZECONF:
      lv_lookup_table[i].subwin = new DirSizeConfPanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case LAYOUTCONF:
      lv_lookup_table[i].subwin = new LayoutPanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case IMEXPORT:
      lv_lookup_table[i].subwin = new ImExportPanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case MAINUICONF:
      lv_lookup_table[i].subwin = new MainUIPanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case EXPERTUICONF:
      lv_lookup_table[i].subwin = new ExpertUIPanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case GENERALCONF:
      lv_lookup_table[i].subwin = new GeneralConfPanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case BOOKMARKCOLORS:
      lv_lookup_table[i].subwin = new BookmarkColorPanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case VOLMANCONF:
      lv_lookup_table[i].subwin = new VolManPanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case PATHJUMPALLOWCONF:
      lv_lookup_table[i].subwin = new PathJumpAllowPanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case DIRECTORYPRESETSCONF:
      lv_lookup_table[i].subwin = new DirectoryPresetsPanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    case KVPPANELCONF:
      lv_lookup_table[i].subwin = new KVPPanel( *win, *tempconfig );
      lv_lookup_table[i].subwin->create();
      break;
    default:
      break;
  }
  if ( lv_lookup_table[i].subwin != NULL && panelcb != NULL ) {
    lv_lookup_table[i].subwin->setConfCB( panelcb );
  }
}
 
bool WConfig::configure( const std::string &panel )
{
  AGUIX *aguix = worker->getAGUIX();
  lv_key_type_t lv_lookup_table[] =
       { { catalog.getLocale( 696 ), "", MAINUICONF, NULL, 0 },
         { catalog.getLocale( 697 ), "", LANG, NULL, 1 },
         { catalog.getLocale( 698 ), "", COLORCONF, NULL, 1 },
         { catalog.getLocale( 15 ), "", PALETTE, NULL, 2 },
         { catalog.getLocale( 699 ), "", UICOLORS, NULL, 2 },
         { catalog.getLocale( 832 ), "", BOOKMARKCOLORS, NULL, 2 },
         { catalog.getLocale( 700 ), "", FONTCONF, NULL, 1 },
         { catalog.getLocale( 650 ), "", MOUSECONF, NULL, 1 },
         { catalog.getLocale( 4 ), "", BUTTONGRPCONF, NULL, 0 },
         { catalog.getLocale( 706 ), "", BUTTON, NULL, 1 },
         { catalog.getLocale( 707 ), "", PATH, NULL, 1 },
         { catalog.getLocale( 6 ), "", FILETYPE, NULL, 0 },
         { catalog.getLocale( 708 ), "", DCDCONF, NULL, 1 },
         { catalog.getLocale( 91 ), "", HOTKEY, NULL, 0 },
         { catalog.getLocale( 701 ), "", LISTCONF, NULL, 0 },
         { catalog.getLocale( 702 ), "", VIEWCONF, NULL, 1 },
         { catalog.getLocale( 703 ), "", OWNERCONF, NULL, 1 },
         { catalog.getLocale( 704 ), "", DIRSIZECONF, NULL, 1 },
         { catalog.getLocale( 439 ), "", TIMECONF, NULL, 1 },
         { catalog.getLocale( 705 ), "", STARTCONF, NULL, 1 },
         { catalog.getLocale( 1332 ), "", DIRECTORYPRESETSCONF, NULL, 1 },
         { catalog.getLocale( 974 ), "", PATHJUMPALLOWCONF, NULL, 0 },
         { catalog.getLocale( 784 ), "", GENERALCONF, NULL, 0 },
         { catalog.getLocale( 709 ), "", EXPERTUICONF, NULL, 0 },
         { catalog.getLocale( 710 ), "", TERMCONF, NULL, 1 },
         { catalog.getLocale( 711 ), "", CACHECONF, NULL, 1 },
         { catalog.getLocale( 368 ), "", CLOCKCONF, NULL, 1 },
         { catalog.getLocale( 569 ), "", LAYOUTCONF, NULL, 1 },
         { catalog.getLocale( 863 ), "", VOLMANCONF, NULL, 1 },
         { catalog.getLocale( 1601 ), "", KVPPANELCONF, NULL, 1 },
         { catalog.getLocale( 396 ), "", IMEXPORT, NULL, 0 } };
  std::map<type_t, lv_key_type_t *> type_lookup;

  AWindow *win = new AWindow( aguix, 10, 10, 10, 10, catalog.getLocale( 0 ) );
  win->create();

  AContainer *ac1 = win->setContainer( new AContainer( win, 1, 2 ), true );
  ac1->setBorderWidth( 5 );
  ac1->setMinSpace( 5 );
  ac1->setMaxSpace( 5 );
  
  AContainer *ac1_1 = ac1->add( new AContainer( win, 2, 1 ), 0, 0 );
  ac1_1->setBorderWidth( 0 );
  ac1_1->setMinSpace( 0 );
  ac1_1->setMaxSpace( 0 );
  
  FieldListView *lv = (FieldListView*)ac1_1->add( new FieldListView( aguix, 0, 0, 10, 400, 0 ),
                                                  0, 0, AContainer::CO_INCH );
  
  AContainer *ac1_2 = ac1->add( new AContainer( win, 2, 1 ), 0, 1 );
  ac1_2->setBorderWidth( 0 );
  ac1_2->setMinSpace( 5 );
  ac1_2->setMaxSpace( -1 );
  Button *okb = (Button*)ac1_2->add( new Button( aguix,
                                                 0,
                                                 0,
                                                 catalog.getLocale( 7 ),
                                                 0 ), 0, 0, AContainer::CO_FIX );
  Button *cb = (Button*)ac1_2->add( new Button( aguix,
                                                0,
                                                0,
                                                catalog.getLocale( 8 ),
                                                0 ), 1, 0, AContainer::CO_FIX );

  for ( unsigned int i = 0; i < sizeof( lv_lookup_table ) / sizeof( lv_lookup_table[0] ); i++ ) {
    int row = lv->addRow();

    std::string s1( lv_lookup_table[i].level * 2, ' ' );
    lv_lookup_table[i].base_key = lv_lookup_table[i].key;
    lv_lookup_table[i].key = s1 + lv_lookup_table[i].key;

    lv->setText( row, 0, lv_lookup_table[i].key );
    lv->setPreColors( row, FieldListView::PRECOLOR_ONLYACTIVE );
    if ( lv_lookup_table[i].type != NONE ) type_lookup[lv_lookup_table[i].type] = &lv_lookup_table[i];
  }
  lv->setHBarState( 0 );
  lv->setVBarState( 0 );
  lv->setDisplayFocus( true );
  lv->setAcceptFocus( true );
  lv->maximizeX();
  lv->maximizeY();
  ac1_1->readLimits();

  WConfig *button_path_hotkey_conf = duplicate();
  WConfig *tempconfig = duplicate();

  MyWConfigPanelCallBack mypanelcb( lv_lookup_table, sizeof( lv_lookup_table ) / sizeof( lv_lookup_table[0] ) );

  int inner_width = 100, inner_height = 100;
  int w, h;

  for ( unsigned int i = 0; i < sizeof( lv_lookup_table ) / sizeof( lv_lookup_table[0] ); i++ ) {
    recreatePanel( i, lv_lookup_table, sizeof( lv_lookup_table ) / sizeof( lv_lookup_table[0] ),
                   win, tempconfig, button_path_hotkey_conf, &mypanelcb );
    if ( lv_lookup_table[i].subwin != NULL ) {
      w = lv_lookup_table[i].subwin->getMinWidth();
      h = lv_lookup_table[i].subwin->getMinHeight();
      if ( w > inner_width ) inner_width = w;
      if ( h > inner_height ) inner_height = h;
    }
  }

  win->setDoTabCycling( true );

  int active_row = 0;

  if ( ! panel.empty() ) {
      // find panel to activate by default
      int row = 0;
      for ( auto &e : lv_lookup_table ) {
          if ( e.base_key == panel ) {
              active_row = row;
              break;
          }
          row++;
      }
  }

  ac1_1->add( lv_lookup_table[active_row].subwin, 1, 0, AContainer::CO_MIN );
  ac1_1->setMinWidth( inner_width, 1, 0 );
  ac1_1->setMinHeight( inner_height, 1, 0 );
  
  win->contMaximize( true );
  lv_lookup_table[active_row].subwin->show();
  lv->setActiveRow( active_row );
  lv->takeFocus();
  win->show();

  if ( m_initial_command.type() != WConfigInitialCommand::NO_OP ) {
      for ( auto &e : lv_lookup_table ) {
          e.subwin->executeInitialCommand( m_initial_command );
      }
      m_initial_command = WConfigInitialCommand();
  }
  
  AGMessage *msg;
  while((msg=aguix->GetMessage(NULL))!=NULL) aguix->ReplyMessage(msg);
  int ende=0;
  while(ende==0) {
    msg=aguix->WaitMessage(win);
    if(msg!=NULL) {
      if(msg->type==AG_CLOSEWINDOW) {
        if(msg->closewindow.window==win->getWindow()) ende=-1;
      } else if ( msg->type == AG_FIELDLV_ONESELECT || msg->type == AG_FIELDLV_MULTISELECT ) {
        if ( msg->fieldlv.lv == lv ) {
          int entry = lv->getActiveRow();
          for ( unsigned int i = 0; i < sizeof( lv_lookup_table ) / sizeof( lv_lookup_table[0] ); i++ ) {
            if ( lv_lookup_table[i].key != lv->getText( entry, 0 ) ) {
              if ( lv_lookup_table[i].subwin != NULL &&
                   lv_lookup_table[i].subwin->isVisible() == true ) {
                lv_lookup_table[i].subwin->hide();
              }
            }
          }

          WConfigPanel *show_panel = NULL;

          for ( unsigned int i = 0; i < sizeof( lv_lookup_table ) / sizeof( lv_lookup_table[0] ); i++ ) {
            if ( lv_lookup_table[i].key == lv->getText( entry, 0 ) ) {
              if ( lv_lookup_table[i].subwin != NULL ) {
                if ( lv_lookup_table[i].subwin->need_recreate() == true ) {
                  lv_lookup_table[i].subwin->saveValues();

                  recreatePanel( i, lv_lookup_table, sizeof( lv_lookup_table ) / sizeof( lv_lookup_table[0] ),
                                 win,
                                 tempconfig,
                                 button_path_hotkey_conf, &mypanelcb );
                }
                show_panel = lv_lookup_table[i].subwin;
                w = show_panel->getMinWidth();
                h = show_panel->getMinHeight();
           
                bool need_maximize = false;
                if ( w > inner_width ) {
                  inner_width = w;
                  need_maximize = true;
                }
                if ( h > inner_height ) {
                  inner_height = h;
                  need_maximize = true;
                }

                ac1_1->add( lv_lookup_table[i].subwin, 1, 0, AContainer::CO_MIN );
                ac1_1->setMinWidth( inner_width, 1, 0 );
                ac1_1->setMinHeight( inner_height, 1, 0 );
                
                if ( need_maximize == true ) {
                  win->contMaximize( true );
                } else {
                  ac1->rearrange();
                }
                break;
              }
            }
          }
          if ( show_panel != NULL ) show_panel->show();
        }
      } else if(msg->type==AG_BUTTONCLICKED) {
        if ( msg->button.button == okb ) {
          ende=1;
        } else if ( msg->button.button == cb ) {
          ende=-1;
        }
      } else if ( msg->type == AG_KEYPRESSED ) {
          if ( win->isParent( msg->key.window, false ) == true ) {
              switch ( msg->key.key ) {
                  case XK_Escape: {
                      int entry = lv->getActiveRow();
                      for ( unsigned int i = 0; i < sizeof( lv_lookup_table ) / sizeof( lv_lookup_table[0] ); i++ ) {
                          if ( lv_lookup_table[i].key == lv->getText( entry, 0 ) ) {
                              if ( lv_lookup_table[i].subwin != NULL ) {
                                  if ( ! lv_lookup_table[i].subwin->escapeInUse() ) {
                                      ende = -1;
                                      break;
                                  }
                              }
                          }
                      }
                      break;
                  }
              }
          }
      }
      aguix->ReplyMessage(msg);
    }

    if ( ende == 1 && checkForNewerConfig() ) {
        std::string str1;
      
        str1 = catalog.getLocale( 629 );
        str1 += "|";
        str1 += catalog.getLocale( 8 );

        int res = Worker::getRequester()->request( catalog.getLocale( 123 ),
                                                   catalog.getLocale( 1096 ),
                                                   str1.c_str(),
                                                   win,
                                                   Requester::REQUEST_NONE );
        if ( res == 1 ) {
            ende = 0;
        }
    }

    if ( ende == -1 ) {
        // cancel but changed config, ask to continue
        std::string str1;
      
        str1 = catalog.getLocale( 11 );
        str1 += "|";
        str1 += catalog.getLocale( 8 );

        int res = Worker::getRequester()->request( catalog.getLocale( 123 ),
                                                   catalog.getLocale( 1550 ),
                                                   str1.c_str(),
                                                   win,
                                                   Requester::REQUEST_NONE );
        if ( res == 1 ) {
            ende = 0;
        }
    }
  }

  if ( ende == 1 ) {
    {
      for ( unsigned int i = 0; i < sizeof( lv_lookup_table ) / sizeof( lv_lookup_table[0] ); i++ ) {
        if ( lv_lookup_table[i].subwin != NULL &&
             lv_lookup_table[i].subwin->isVisible() == true ) {
          lv_lookup_table[i].subwin->hide();
        }
      }
      for ( unsigned int i = 0; i < sizeof( lv_lookup_table ) / sizeof( lv_lookup_table[0] ); i++ ) {
        if ( lv_lookup_table[i].subwin != NULL ) {
          lv_lookup_table[i].subwin->saveValues();
        }
      }
    }
    setButtons( button_path_hotkey_conf->getButtons() );
    setHotkeys( button_path_hotkey_conf->getHotkeys() );
    setPaths( button_path_hotkey_conf->getPaths() );
    setRows( button_path_hotkey_conf->getRows() );
    setColumns( button_path_hotkey_conf->getColumns() );

    setLang(tempconfig->getLang());
    setTerminalBin(tempconfig->getTerminalBin());
    setCacheSize(tempconfig->getCacheSize());
    for ( int i = 0; i < 2; i++ ) {
      setHBarTop(i,tempconfig->getHBarTop(i));
      setVBarLeft(i,tempconfig->getVBarLeft(i));
      setHBarHeight(i,tempconfig->getHBarHeight(i));
      setVBarWidth(i,tempconfig->getVBarWidth(i));
      setVisCols( i, tempconfig->getVisCols( i ) );
      setShowHeader( i, tempconfig->getShowHeader( i ) );
      setStartDir(i,tempconfig->getStartDir(i));

      setPathEntryOnTop( i, tempconfig->getPathEntryOnTop( i ) );
    }
    setFontNames( tempconfig->getFontNames() );
    setFiletypes(tempconfig->getFiletypes());
    setColors(tempconfig->getColors());
    setOwnerstringtype(tempconfig->getOwnerstringtype());
    setClockbarMode(tempconfig->getClockbarMode());
    setClockbarUpdatetime(tempconfig->getClockbarUpdatetime());
    setClockbarCommand(tempconfig->getClockbarCommand());
    setClockbarCustom( tempconfig->getClockbarCustom( 0 ), 0 );
    setClockbarCustom( tempconfig->getClockbarCustom( 1 ), 1 );
    setClockbarHints( tempconfig->getClockbarHints() );
    setDontCheckDirs(tempconfig->getDontCheckDirs());
    setDontCheckVirtual( tempconfig->getDontCheckVirtual() );
    setShowStringForDirSize(tempconfig->getShowStringForDirSize());
    setStringForDirSize(tempconfig->getStringForDirSize());
    setLayoutOrders( tempconfig->getLayoutOrders() );
    setLayoutButtonVert( tempconfig->getLayoutButtonVert() );
    setLayoutListviewVert( tempconfig->getLayoutListviewVert() );
    setLayoutListViewWeight( tempconfig->getLayoutListViewWeight() );
    setLayoutWeightRelToActive( tempconfig->getLayoutWeightRelToActive() );

    setMouseSelectButton( tempconfig->getMouseSelectButton() );
    setMouseActivateButton( tempconfig->getMouseActivateButton() );
    setMouseScrollButton( tempconfig->getMouseScrollButton() );
    setMouseContextButton( tempconfig->getMouseContextButton() );
    setMouseActivateMod( tempconfig->getMouseActivateMod() );
    setMouseScrollMod( tempconfig->getMouseScrollMod() );
    setMouseContextMod( tempconfig->getMouseContextMod() );
    setMouseSelectMethod( tempconfig->getMouseSelectMethod() );
    setMouseContextMenuWithDelayedActivate( tempconfig->getMouseContextMenuWithDelayedActivate() );
    setDateFormat( tempconfig->getDateFormat() );
    setDateFormatString( tempconfig->getDateFormatString() );
    setDateSubst( tempconfig->getDateSubst() );
    setTimeFormat( tempconfig->getTimeFormat() );
    setTimeFormatString( tempconfig->getTimeFormatString() );
    setDateBeforeTime( tempconfig->getDateBeforeTime() );

    setColorDefs( tempconfig->getColorDefs() );

    setSaveWorkerStateOnExit( tempconfig->getSaveWorkerStateOnExit() );

    setVMMountCommand( tempconfig->getVMMountCommand() );
    setVMUnmountCommand( tempconfig->getVMUnmountCommand() );
    setVMFStabFile( tempconfig->getVMFStabFile() );
    setVMMtabFile( tempconfig->getVMMtabFile() );
    setVMPartitionFile( tempconfig->getVMPartitionFile() );
    setVMRequestAction( tempconfig->getVMRequestAction() );
    setVMEjectCommand( tempconfig->getVMEjectCommand() );
    setVMCloseTrayCommand( tempconfig->getVMCloseTrayCommand() );
    setVMPreferredUdisksVersion( tempconfig->getVMPreferredUdisksVersion() );
  
    setUseStringCompareMode( tempconfig->getUseStringCompareMode() );
    setApplyWindowDialogType( tempconfig->getApplyWindowDialogType() );
    setUseExtendedRegEx( tempconfig->getUseExtendedRegEx() );

    setPathJumpAllowDirs( tempconfig->getPathJumpAllowDirs() );
    setPathJumpStoreFilesAlways( tempconfig->getPathJumpStoreFilesAlways() );

    setFaceDB( tempconfig->getFaceDB() );

    setRestoreTabsMode( tempconfig->getRestoreTabsMode() );
    setStoreTabsMode( tempconfig->getStoreTabsMode() );

    setTerminalReturnsEarly( tempconfig->getTerminalReturnsEarly() );

    setDisableBGCheckPrefix( tempconfig->getDisableBGCheckPrefix() );

    setDirectoryPresets( tempconfig->getDirectoryPresets() );

    setKVPPool( tempconfig->getKVPPool() );

    save();
    applyLanguage();
  } else {
    applyColorList( getColors() );
  }

  delete win;
  delete button_path_hotkey_conf;
  delete tempconfig;

  initFixTypes();
  
  return ( ende == 1 ) ? true : false;
}

int WConfig::addButtons( List *bl )
{
  int erg = 0, id;
  List *orig_buttons, *orig_buttons_copy;
  WCButton *b1;

  if ( bl == NULL ) return 1;

  orig_buttons = getButtons();
  orig_buttons_copy = new List();
  id = orig_buttons->initEnum();
  b1 = (WCButton*)orig_buttons->getFirstElement( id );
  while ( b1 != NULL ) {
    orig_buttons_copy->addElement( b1->duplicate() );
    b1 = (WCButton*)orig_buttons->getNextElement( id );
  }
  orig_buttons->closeEnum( id );

  id = bl->initEnum();

  b1 = (WCButton*)bl->getFirstElement( id );
  while ( b1 != NULL && erg == 0 ) {
    erg = addButton( orig_buttons_copy, b1 );
    b1 = (WCButton*)bl->getNextElement( id );
  }

  bl->closeEnum( id );

  if ( erg == 0 )
    setButtons( orig_buttons_copy );

  id = orig_buttons_copy->initEnum();
  b1 = (WCButton*)orig_buttons_copy->getFirstElement( id );
  while ( b1 != NULL ) {
    delete b1;
    b1 = (WCButton*)orig_buttons_copy->getNextElement( id );
  }
  orig_buttons_copy->closeEnum( id );
  delete orig_buttons_copy;

  return erg;
}

int WConfig::addHotkeys( List *hl )
{
  int erg = 0, id;
  List *orig_hotkeys, *orig_hotkeys_copy;
  WCHotkey *h1;

  if ( hl == NULL ) return 1;

  orig_hotkeys = getHotkeys();
  orig_hotkeys_copy = new List();
  id = orig_hotkeys->initEnum();
  h1 = (WCHotkey*)orig_hotkeys->getFirstElement( id );
  while ( h1 != NULL ) {
    orig_hotkeys_copy->addElement( h1->duplicate() );
    h1 = (WCHotkey*)orig_hotkeys->getNextElement( id );
  }
  orig_hotkeys->closeEnum( id );

  id = hl->initEnum();

  h1 = (WCHotkey*)hl->getFirstElement( id );
  while ( h1 != NULL && erg == 0 ) {
    erg = addHotkey( orig_hotkeys_copy, h1 );
    h1 = (WCHotkey*)hl->getNextElement( id );
  }

  hl->closeEnum( id );

  if ( erg == 0 )
    setHotkeys( orig_hotkeys_copy );

  id = orig_hotkeys_copy->initEnum();
  h1 = (WCHotkey*)orig_hotkeys_copy->getFirstElement( id );
  while ( h1 != NULL ) {
    delete h1;
    h1 = (WCHotkey*)orig_hotkeys_copy->getNextElement( id );
  }
  orig_hotkeys_copy->closeEnum( id );
  delete orig_hotkeys_copy;

  return erg;
}

int WConfig::addFiletypes( List *fl, bool init_fix_types )
{
  int erg = 0, id;
  List *orig_filetypes, *orig_filetypes_copy;
  WCFiletype *f1;

  if ( fl == NULL ) return 1;

  orig_filetypes = getFiletypes();
  orig_filetypes_copy = new List();
  id = orig_filetypes->initEnum();
  f1 = (WCFiletype*)orig_filetypes->getFirstElement( id );
  while ( f1 != NULL ) {
    orig_filetypes_copy->addElement( f1->duplicate() );
    f1 = (WCFiletype*)orig_filetypes->getNextElement( id );
  }
  orig_filetypes->closeEnum( id );

  id = fl->initEnum();

  f1 = (WCFiletype*)fl->getFirstElement( id );
  while ( f1 != NULL && erg == 0 ) {
    erg = addFiletype( orig_filetypes_copy, f1 );
    f1 = (WCFiletype*)fl->getNextElement( id );
  }

  fl->closeEnum( id );

  if ( erg == 0 ) {
    setFiletypes( orig_filetypes_copy );
    if ( init_fix_types ) {
        initFixTypes();
    }
  }

  id = orig_filetypes_copy->initEnum();
  f1 = (WCFiletype*)orig_filetypes_copy->getFirstElement( id );
  while ( f1 != NULL ) {
    delete f1;
    f1 = (WCFiletype*)orig_filetypes_copy->getNextElement( id );
  }
  orig_filetypes_copy->closeEnum( id );
  delete orig_filetypes_copy;

  return erg;
}

int WConfig::addButton( List *bl, WCButton *im_b1_orig )
{
  WCButton *im_b1;
  int ende = 0, maxcols;
  std::string str1;

  /* 1.resolve any shortkey problem
   * 2.add button to given list
   *   colors could be wrong for the imported buttons!
   */

  maxcols = getColors()->size();

  if ( im_b1_orig == NULL ) return 1;
  
  im_b1 = im_b1_orig->duplicate();
  
  ende = fixDoubleKeys( bl, getPaths(), getHotkeys(), im_b1, NULL );

  if ( im_b1->getFG() >= maxcols ) im_b1->setFG( maxcols - 1 );
  if ( im_b1->getBG() >= maxcols ) im_b1->setBG( maxcols - 1 );
  
  if ( ende != 0 ) {
    delete im_b1;
    return 1;
  }

  bl->addElement( im_b1 );
  return 0;
}

int WConfig::addHotkey( List *hl, WCHotkey *im_h_orig )
{
  WCHotkey *im_h1;
  int ende = 0;
  std::string str1;

  /* 1.resolve any shortkey problem
   * 2.add buttons banks to this config
   *   colors could be wrong for the imported buttons!
   * 3.add hotkeys to this config
   * 4.add normal filetypes to this config
   * 5.ask for the special types (if any)
   *   leave the current
   *   or take the new
   */

  if ( im_h_orig == NULL ) return 1;

  im_h1 = im_h_orig->duplicate();

  ende = fixDoubleKeys( getButtons(), getPaths(), hl, NULL, im_h1 );

  if ( ende != 0 ) {
    delete im_h1;
    return 1;
  }

  hl->addElement( im_h1 );
  return 0;
}

int WConfig::addFiletype( List *fl, WCFiletype *im_f_orig )
{
  WCFiletype *im_f1, *f1;
  char *textstr;
  int erg, im_id;
  std::string str1;
  Requester req( worker->getAGUIX() );

  if ( im_f_orig == NULL ) return 1;

  im_f1 = im_f_orig->duplicate();
  
  // here we need a two-pass-run over the types
  // 1.For each unique type in importconfig
  //   find equal unique
  //   Ask which should be used and add it
  // 2.add all normal types from current config and then from importconfig

  if ( im_f1->getinternID() != NORMALTYPE ) {
    // not a normal type
    // because special types are unique, ask the user
    // which should be used

    im_id = fl->initEnum();
    
    // find new type for this id
    f1 = (WCFiletype*)fl->getFirstElement( im_id );
    while ( f1 != NULL ) {
      if ( f1->getinternID() == im_f1->getinternID() ) break;
      f1 = (WCFiletype*)fl->getNextElement( im_id );
    }
    fl->closeEnum( im_id );
    
    if ( f1 != NULL ) {
      // same unique type found
      textstr = (char*)_allocsafe( strlen( catalog.getLocale( 429 ) ) +
                                   strlen( im_f1->getName().c_str() ) +
                                   strlen( f1->getName().c_str() ) + 1 );
      sprintf( textstr, catalog.getLocale( 429 ), im_f1->getName().c_str(), f1->getName().c_str() );
      
      str1 = catalog.getLocale( 427 );
      str1 += "|";
      str1 += catalog.getLocale( 428 );
      erg = req.request( catalog.getLocale( 123 ), textstr, str1.c_str() );
      _freesafe( textstr );
      if ( erg == 1 ) {
        fl->addElement( im_f1 );
        fl->removeElement( f1 );
        delete f1;
      } else {
        delete im_f1;
      }
    } else {
      fl->addElement( im_f1 );
    }
  } else {
    fl->addElement( im_f1 );
  }
  return 0;
}

/**
 * fixDoubleKeys checks the given button or hotkey for possible shortkey conflicts
 * in any given list and possibly removes conflicts
 */
int WConfig::fixDoubleKeys( List *bl, List *pl, List *hl, WCButton *im_b1, WCHotkey *im_h1 )
{
  WCButton *b1_return;
  WCHotkey *h1_return;
  WCPath *p1_return;
  char *textstr;
  int ende = 0, erg, id;
  std::string str1;
  Requester req( Worker::getAGUIX() );
  WCDoubleShortkey *dk;
  List *dkeys;

  if ( im_b1 == NULL && im_h1 == NULL ) return 1;
  if ( im_b1 != NULL && im_h1 != NULL ) return 1;
  
  dkeys = ( im_b1 != NULL ) ? im_b1->getDoubleKeys() : im_h1->getDoubleKeys();
  
  id = dkeys->initEnum();
  dk = (WCDoubleShortkey*)dkeys->getFirstElement( id );
  while ( dk != NULL ) {
    if ( findDoubleShortkey( dk, bl, pl, hl,
                             &b1_return, &p1_return, &h1_return ) != 0 ) {
      // there is already an element with this shortkey
      if ( getAlwaysKeepOldKey() == true ) {

        if ( im_b1 != NULL )
          im_b1->removeKey( dk );
        else
          im_h1->removeKey( dk );

      } else {
        if ( b1_return != NULL ) {
          // "The new button/hotkey %s uses the same shortkey as the button %s!"
          if ( im_b1 != NULL ) {
            textstr = (char*)_allocsafe( strlen( catalog.getLocale( 419 ) ) +
                                         strlen( im_b1->getText() ) +
                                         strlen( b1_return->getText() ) + 1 );
            sprintf( textstr, catalog.getLocale( 419 ), im_b1->getText(), b1_return->getText() );
          } else {
            textstr = (char*)_allocsafe( strlen( catalog.getLocale( 420 ) ) +
                                         strlen( im_h1->getName() ) +
                                         strlen( b1_return->getText() ) + 1 );
            sprintf( textstr, catalog.getLocale( 420 ), im_h1->getName(), b1_return->getText() );
          }
          str1 = catalog.getLocale( 425 );
          str1 += "|";
          str1 += catalog.getLocale( 431 );
          str1 += "|";
          str1 += catalog.getLocale( 426 );
          str1 += "|";
          str1 += catalog.getLocale( 8 );
          erg = req.request( catalog.getLocale( 123 ), textstr, str1.c_str() );
          _freesafe(textstr);
          
          if ( erg == 2 ) {
            // use new
            b1_return->removeKey( dk );
          } else if ( erg == 1 || erg == 0 ) {
            // leave original

            if ( im_b1 != NULL )
              im_b1->removeKey( dk );
            else
              im_h1->removeKey( dk );
            
            if ( erg == 1 ) setAlwaysKeepOldKey( true );
          } else {
            ende = -1;
          }
        } else if ( p1_return != NULL ) {
          // "The new button/hotkey %s uses the same shortkey as the path %s!"
          if ( im_b1 != NULL ) {
            textstr = (char*)_allocsafe( strlen( catalog.getLocale( 423 ) ) +
                                         strlen( im_b1->getText() ) +
                                         strlen( p1_return->getName() ) + 1 );
            sprintf( textstr, catalog.getLocale( 423 ), im_b1->getText(), p1_return->getName() );
          } else {
            textstr = (char*)_allocsafe( strlen( catalog.getLocale( 424 ) ) +
                                         strlen( im_h1->getName() ) +
                                         strlen( p1_return->getName() ) + 1 );
            sprintf( textstr, catalog.getLocale( 424 ), im_h1->getName(), p1_return->getName() );
          }
          
          str1 = catalog.getLocale( 425 );
          str1 += "|";
          str1 += catalog.getLocale( 431 );
          str1 += "|";
          str1 += catalog.getLocale( 426 );
          str1 += "|";
          str1 += catalog.getLocale( 8 );
          erg = req.request( catalog.getLocale( 123 ), textstr, str1.c_str() );
          _freesafe(textstr);
          
          if ( erg == 2 ) {
            // use new
            p1_return->removeKey( dk );
          } else if ( erg == 1 || erg == 0 ) {

            // leave original
            if ( im_b1 != NULL )
              im_b1->removeKey( dk );
            else
              im_h1->removeKey( dk );

            if ( erg == 1 ) setAlwaysKeepOldKey( true );
          } else ende = -1;
        } else if ( h1_return != NULL ) {
          // "The new button/hotkey %s uses the same shortkey as the hotkey %s!"
          if ( im_b1 != NULL ) {
            textstr = (char*)_allocsafe( strlen( catalog.getLocale( 421 ) ) +
                                         strlen( im_b1->getText() ) +
                                         strlen( h1_return->getName() ) + 1 );
            sprintf( textstr, catalog.getLocale( 421 ), im_b1->getText(), h1_return->getName() );
          } else {
            textstr = (char*)_allocsafe( strlen( catalog.getLocale( 422 ) ) +
                                         strlen( im_h1->getName() ) +
                                         strlen( h1_return->getName() ) + 1 );
            sprintf( textstr, catalog.getLocale( 422 ), im_h1->getName(), h1_return->getName() );
          }
          
          str1 = catalog.getLocale( 425 );
          str1 += "|";
          str1 += catalog.getLocale( 431 );
          str1 += "|";
          str1 += catalog.getLocale( 426 );
          str1 += "|";
          str1 += catalog.getLocale( 8 );
          erg = req.request( catalog.getLocale( 123 ), textstr, str1.c_str() );
          _freesafe(textstr);
          
          if ( erg == 2 ) {
            // use new
            h1_return->removeKey( dk );
          } else if ( erg == 1 || erg == 0 ) {

            // leave original
            if ( im_b1 != NULL )
              im_b1->removeKey( dk );
            else
              im_h1->removeKey( dk );
            if ( erg == 1 ) setAlwaysKeepOldKey( true );
          } else ende = -1;
        }
      }
    }
    dk = (WCDoubleShortkey*)dkeys->getNextElement( id );
  }
  dkeys->closeEnum( id );
  
  if ( ende != 0 ) return 1;
  return 0;
}

int WConfig::fixDoubleKeys( List *bl, List *pl, List *hl, List *button_check, List *hotkey_check )
{
  int erg = 0;
  int id;

  if ( button_check != NULL ) {
    id = button_check->initEnum();
    WCButton *b1 = (WCButton*)button_check->getFirstElement( id );
    while ( b1 != NULL && erg == 0 ) {
      erg = fixDoubleKeys( bl, pl, hl, b1, NULL );
      b1 = (WCButton*)button_check->getNextElement( id );
    }
    button_check->closeEnum( id );
  }

  if ( hotkey_check != NULL && erg == 0 ) {
    id = hotkey_check->initEnum();
    WCHotkey *h1 = (WCHotkey*)hotkey_check->getFirstElement( id );
    while ( h1 != NULL && erg == 0 ) {
      erg = fixDoubleKeys( bl, pl, hl, NULL, h1 );
      h1 = (WCHotkey*)hotkey_check->getNextElement( id );
    }
    hotkey_check->closeEnum( id );
  }
  return erg;
}

bool WConfig::getAlwaysKeepOldKey()
{
  return always_keep_old_key;
}

void WConfig::setAlwaysKeepOldKey( bool nv )
{
  always_keep_old_key = nv;
}

int WConfig::getNrOfPreDates()
{
  return sizeof( predefined_dates ) / sizeof( predefined_dates[0] );
}

int WConfig::getNrOfPreTimes()
{
  return sizeof( predefined_times ) / sizeof( predefined_times[0] );
}

const char *WConfig::getPreDate( int pos )
{
  int i = 0;
  if ( pos >= 0 && pos < getNrOfPreDates() ) {
    i = pos;
  }
  return predefined_dates[i];
}

const char *WConfig::getPreTime( int pos )
{
  int i = 0;
  if ( pos >= 0 && pos < getNrOfPreTimes() ) {
    i = pos;
  }
  return predefined_times[i];
}

void WConfig::setColorDefs( const ColorDef &cols )
{
    _color_defs = cols;
}

const WConfig::ColorDef &WConfig::getColorDefs() const
{
    return _color_defs;
}

std::string WConfig::queryNewActionName() const
{
    int trow;
    AGUIX *aguix = worker->getAGUIX();
    AWindow *win = new AWindow( aguix, 10, 10, 10, 10, catalog.getLocale( 774 ), AWindow::AWINDOW_DIALOG );
    win->create();

    AContainer *ac1 = win->setContainer( new AContainer( win, 1, 4 ), true );
    ac1->setMinSpace( 5 );
    ac1->setMaxSpace( 5 );

    AContainer *ac1_2 = ac1->add( new AContainer( win, 2, 1 ), 0, 0 );
    ac1_2->setMinSpace( 5 );
    ac1_2->setMaxSpace( 5 );
    ac1_2->setBorderWidth( 0 );
    ac1_2->add( new Text( aguix, 0, 0, catalog.getLocale( 775 ) ), 0, 0, AContainer::CO_FIX );
    StringGadget *name_sg = (StringGadget*)ac1_2->add( new StringGadget( aguix, 0, 0,
                                                                         100,
                                                                         "", 0 ), 1, 0, AContainer::CO_INCW );

    ac1->add( new Text( aguix, 0, 0, catalog.getLocale( 776 ) ), 0, 1, AContainer::CO_INCWNR );

    FieldListView *name_lv = (FieldListView*)ac1->add( new FieldListView( aguix,
                                                                          0,
                                                                          0,
                                                                          100,
                                                                          10 * aguix->getCharHeight(),
                                                                          0 ), 0, 2, AContainer::CO_MIN );
    name_lv->setHBarState(2);
    name_lv->setVBarState(2);
    name_lv->setNrOfFields( 3 );
    name_lv->setFieldWidth( 1, 1 );
    
    std::vector<std::string> custom_names;
    getAllCustomNames( custom_names );
    
    std::sort( custom_names.begin(), custom_names.end() );
    
    for ( std::vector<std::string>::const_iterator it1 = custom_names.begin();
          it1 != custom_names.end();
          it1++ ) {
        trow = name_lv->addRow();
        name_lv->setPreColors( trow, FieldListView::PRECOLOR_ONLYACTIVE );
        name_lv->setText( trow, 0, *it1 );
    }
    
    AContainer *ac1_3 = ac1->add( new AContainer( win, 2, 1 ), 0, 3 );
    ac1_3->setMinSpace( 5 );
    ac1_3->setMaxSpace( -1 );
    ac1_3->setBorderWidth( 0 );
    Button *okb =(Button*)ac1_3->add( new Button( aguix,
                                                  0,
                                                  0,
                                                  catalog.getLocale( 11 ),
                                                  0 ), 0, 0, AContainer::CO_FIX );
    Button *cancelb = (Button*)ac1_3->add( new Button( aguix,
                                                       0,
						       0,
 						       catalog.getLocale( 8 ),
						       0 ), 1, 0, AContainer::CO_FIX );

  
    name_sg->takeFocus();
            
    win->setDoTabCycling( true );
    win->contMaximize( true );
    win->show();
  
    AGMessage *msg;
    while ( ( msg = aguix->GetMessage( NULL ) ) != NULL ) aguix->ReplyMessage( msg );
    int ende = 0;
    while ( ende == 0 ) {
        msg = aguix->WaitMessage( win );
        if ( msg != NULL ) {
            if ( msg->type == AG_CLOSEWINDOW ) {
                if ( msg->closewindow.window == win->getWindow() ) ende = -1;
            } else if ( msg->type == AG_BUTTONCLICKED ) {
                if ( msg->button.button == okb ) ende = 1;
                else if ( msg->button.button == cancelb ) ende = -1;
            } else if ( msg->type == AG_FIELDLV_ONESELECT ) {
                if ( msg->fieldlv.lv == name_lv ) {
                    if ( name_lv->isValidRow( msg->fieldlv.row ) == true ) {
                        std::string s1 = name_lv->getText( msg->fieldlv.row, 0 );
                        name_sg->setText( s1.c_str() );
                    }
                }
            } else if ( msg->type == AG_STRINGGADGET_OK ) {
                if ( msg->stringgadget.sg == name_sg ) {
                    ende = 1;
                }
            }
        }
        aguix->ReplyMessage( msg );
    }
  
    std::string res = "";
    if ( ende == 1 ) {
        res = name_sg->getText();
    }
    
    delete win;
    
    return res;
}

int WConfig::getAllCustomNames( std::vector<std::string> &custom_names ) const
{
    std::set<std::string> names;

    std::unique_ptr< FlatTypeList > types = getFlatTypeList();

    for ( int e = 0; e < types->getNrOfEntries(); e++ ) {
	std::list<std::string> single_names;
	types->getEntry( e ).filetype->fillNamesOfCustomActions( false, single_names );
	
	for ( std::list<std::string>::const_iterator cit2 = single_names.begin();
	      cit2 != single_names.end();
	      cit2++ ) {
            names.insert( *cit2 );
	}
    }

    for ( std::set<std::string>::const_iterator cit3 = names.begin();
	  cit3 != names.end();
	  cit3++ ) {
	custom_names.push_back( *cit3 );
    }

    return 0;
}

void WConfig::setSaveWorkerStateOnExit( bool nv )
{
    m_save_worker_state_on_exit = nv;
}

bool WConfig::getSaveWorkerStateOnExit() const
{
    return m_save_worker_state_on_exit;
}

void WConfig::setFontName( font_type_t fonttype, const std::string &name )
{
    m_font_names[fonttype] = name;
}

std::string WConfig::getFontName( font_type_t fonttype )
{
    if ( m_font_names.count( fonttype ) > 0 ) {
        return m_font_names[fonttype];
    }
    return "";
}

void WConfig::setFontNames( const std::map< font_type_t, std::string > &font_names )
{
    m_font_names = font_names;
}

std::map< WConfig::font_type_t, std::string > WConfig::getFontNames() const
{
    return m_font_names;
}

void WConfig::setVMMountCommand( const std::string &cmd )
{
    m_vm_settings.mount_command = cmd;
}

std::string WConfig::getVMMountCommand() const
{
    return m_vm_settings.mount_command;
}

void WConfig::setVMUnmountCommand( const std::string &cmd )
{
    m_vm_settings.unmount_command = cmd;
}

std::string WConfig::getVMUnmountCommand() const
{
    return m_vm_settings.unmount_command;
}

void WConfig::setVMFStabFile( const std::string &filename )
{
    m_vm_settings.fstab_file = filename;
}

std::string WConfig::getVMFStabFile() const
{
    return m_vm_settings.fstab_file;
}

void WConfig::setVMMtabFile( const std::string &filename )
{
    m_vm_settings.mtab_file = filename;
}

std::string WConfig::getVMMtabFile() const
{
    return m_vm_settings.mtab_file;
}

void WConfig::setVMPartitionFile( const std::string &filename )
{
    m_vm_settings.part_file = filename;
}

std::string WConfig::getVMPartitionFile() const
{
    return m_vm_settings.part_file;
}

void WConfig::setVMRequestAction( bool nv )
{
    m_vm_settings.request_action = nv;
}

bool WConfig::getVMRequestAction() const
{
    return m_vm_settings.request_action;
}

void WConfig::setVMEjectCommand( const std::string &cmd )
{
    m_vm_settings.eject_command = cmd;
}

std::string WConfig::getVMEjectCommand() const
{
    return m_vm_settings.eject_command;
}

void WConfig::setVMCloseTrayCommand( const std::string &cmd )
{
    m_vm_settings.closetray_command = cmd;
}

std::string WConfig::getVMCloseTrayCommand() const
{
    return m_vm_settings.closetray_command;
}

void WConfig::setVMPreferredUdisksVersion( int version )
{
    if ( version == 1 || version == 2 ) {
        m_vm_settings.preferred_udisks_version = version;
    }
}

int WConfig::getVMPreferredUdisksVersion() const
{
    return m_vm_settings.preferred_udisks_version;
}

void WConfig::setUseStringCompareMode( StringComparator::string_comparator_modes nv )
{
    m_use_string_compare_mode = nv;
}

StringComparator::string_comparator_modes WConfig::getUseStringCompareMode() const
{
    return m_use_string_compare_mode;
}

void WConfig::setUseExtendedRegEx( bool nv )
{
    m_use_extended_regex = nv;
}

bool WConfig::getUseExtendedRegEx() const
{
    return m_use_extended_regex;
}

void WConfig::setPathJumpAllowDirs( const std::list< std::string > &l )
{
    m_pathjump_allow_dirs = l;
}

const std::list< std::string > &WConfig::getPathJumpAllowDirs()
{
  return m_pathjump_allow_dirs;
}

void WConfig::setPathJumpStoreFilesAlways( bool nv )
{
    m_pathjump_store_files_always = nv;
}

bool WConfig::getPathJumpStoreFilesAlways() const
{
    return m_pathjump_store_files_always;
}

void WConfig::setApplyWindowDialogType( bool nv )
{
    m_apply_window_dialog_type = nv;
}

bool WConfig::getApplyWindowDialogType() const
{
    return m_apply_window_dialog_type;
}

void WConfig::setLoadedVersion( int major,
                                int minor,
                                int patch )
{
    m_loaded_major_version = major;
    m_loaded_minor_version = minor;
    m_loaded_patch_version = patch;
}

void WConfig::getLoadedVersion( int &major,
                                int &minor,
                                int &patch )
{
    major = m_loaded_major_version;
    minor = m_loaded_minor_version;
    patch = m_loaded_patch_version;
}

Worker *WConfig::getWorker()
{
    return worker;
}

void WConfig::setFaceDB( const FaceDB &facedb )
{
    m_facedb = facedb;
}

const FaceDB &WConfig::getFaceDB() const
{
    return m_facedb;
}

FaceDB WConfig::getFaceDB()
{
    return m_facedb;
}

void WConfig::applyNewFacesFromList( const std::list< std::pair< std::string, int > > &faces )
{
    FaceDB new_faces;

    for ( auto &face_descr : faces ) {
        if ( ! new_faces.hasFace( face_descr.first ) ) {
            continue;
        }

        Face f = new_faces.getFace( face_descr.first );
        f.setColor( face_descr.second );

        new_faces.setFace( f );
    }

    setFaceDB( new_faces );
}

void WConfig::setRestoreTabsMode( restore_tabs_mode_t v )
{
    m_restore_tabs_mode = v;
}

WConfig::restore_tabs_mode_t WConfig::getRestoreTabsMode() const
{
    return m_restore_tabs_mode;
}

void WConfig::setStoreTabsMode( store_tabs_mode_t v )
{
    m_store_tabs_mode = v;
}

WConfig::store_tabs_mode_t WConfig::getStoreTabsMode() const
{
    return m_store_tabs_mode;
}

void WConfig::setTerminalReturnsEarly( bool nv )
{
    m_terminal_returns_early = nv;
}

bool WConfig::getTerminalReturnsEarly() const
{
    return m_terminal_returns_early;
}

void WConfig::setDirectoryPresets( const std::map< std::string, struct directory_presets > &presets )
{
    m_directory_presets = presets;
}

const std::map< std::string, struct directory_presets > &WConfig::getDirectoryPresets() const
{
    return m_directory_presets;
}

void WConfig::insertFileTypeFlag( StringGadget *sg, WCFiletype *ft )
{
    if ( ! sg ) return;

    FlagReplacer::FlagHelp flags;

    flags.registerFlag( "{mimetype}", catalog.getLocale( 1342 ) );

    std::string str1 = FlagReplacer::requestFlag( flags );

    if ( str1.length() > 0 ) {
        sg->insertAtCursor( str1.c_str() );
    }
}

void WConfig::setInitialCommand( const WConfigInitialCommand &cmd )
{
    m_initial_command = cmd;
}

void WConfig::setDisableBGCheckPrefix( const std::string &prefix )
{
    m_disable_bg_check_prefix = prefix;
}

const std::string WConfig::getDisableBGCheckPrefix() const
{
    return m_disable_bg_check_prefix;
}

void WConfig::setKVPPool( const WConfigKVPPool &kvp )
{
    *m_kvp_pool = kvp;
}

const WConfigKVPPool &WConfig::getKVPPool() const
{
    return *m_kvp_pool;
}

void WConfig::applyKVPPool()
{
    AKVPPool::setGlobalKVPPool( m_kvp_pool );
}
