@Override
    public View getGroupView(
        int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
      View v = convertView;
      LocalIndexInfo group = getGroup(groupPosition);
      if (v == null) {
        LayoutInflater inflater = getLayoutInflater();
        v =
            inflater.inflate(
                net.osmand.plus.R.layout.local_index_list_item_category, parent, false);
      }
      StringBuilder t =
          new StringBuilder(group.getType().getHumanString(LocalIndexesActivity.this));
      if (group.isBackupedData()) {
        t.append(" - ").append(getString(R.string.local_indexes_cat_backup));
      }
      TextView nameView = ((TextView) v.findViewById(R.id.local_index_category_name));
      t.append("  [").append(getChildrenCount(groupPosition));
      if (getString(R.string.local_index_items).length() > 0) {
        t.append(" ").append(getString(R.string.local_index_items));
      }
      if (getString(R.string.local_index_items).length() > 0) {
        t.append(" ").append(getString(R.string.local_index_items));
      }
      List<LocalIndexInfo> list = data.get(group);
      int size = 0;
      for (int i = 0; i < list.size(); i++) {
        int sz = list.get(i).getSize();
        if (sz < 0) {
          size = 0;
          break;
        } else {
          size += sz;
        }
      }
      size = size / (1 << 10);
      if (size > 0) {
        t.append(", ").append(size).append(" MB");
      }
      t.append("]");
      nameView.setText(t.toString());
      if (!group.isBackupedData()) {
        nameView.setTypeface(Typeface.DEFAULT, Typeface.NORMAL);
      } else {
        nameView.setTypeface(Typeface.DEFAULT, Typeface.ITALIC);
      }

      return v;
    }
 public void delete(LocalIndexInfo[] values) {
   for (LocalIndexInfo i : values) {
     LocalIndexInfo c = findCategory(i, i.isBackupedData());
     if (c != null) {
       data.get(c).remove(i);
     }
   }
   listAdapter.notifyDataSetChanged();
 }
 public void addLocalIndexInfo(LocalIndexInfo info) {
   int found = -1;
   // search from end
   for (int i = category.size() - 1; i >= 0; i--) {
     LocalIndexInfo cat = category.get(i);
     if (cat.getType() == info.getType() && info.isBackupedData() == cat.isBackupedData()) {
       found = i;
       break;
     }
   }
   if (found == -1) {
     found = category.size();
     category.add(new LocalIndexInfo(info.getType(), info.isBackupedData()));
   }
   if (!data.containsKey(category.get(found))) {
     data.put(category.get(found), new ArrayList<LocalIndexInfo>());
   }
   data.get(category.get(found)).add(info);
 }
 public void filterCategories(boolean backup) {
   List<LocalIndexInfo> filter = new ArrayList<LocalIndexInfo>();
   List<LocalIndexInfo> source = filterCategory == null ? category : filterCategory;
   for (LocalIndexInfo info : source) {
     if (info.isBackupedData() == backup) {
       filter.add(info);
     }
   }
   filterCategory = filter;
   notifyDataSetChanged();
 }
 public LocalIndexInfo findCategory(LocalIndexInfo val, boolean backuped) {
   for (LocalIndexInfo i : category) {
     if (i.isBackupedData() == backuped && val.getType() == i.getType()) {
       return i;
     }
   }
   LocalIndexInfo newCat = new LocalIndexInfo(val.getType(), backuped);
   category.add(newCat);
   data.put(newCat, new ArrayList<LocalIndexInfo>());
   return newCat;
 }
 private File getFileToRestore(LocalIndexInfo i) {
   if (i.isBackupedData()) {
     File parent = new File(i.getPathToData()).getParentFile();
     if (i.getType() == LocalIndexType.GPX_DATA) {
       parent = settings.extendOsmandPath(ResourceManager.GPX_PATH);
     } else if (i.getType() == LocalIndexType.MAP_DATA) {
       parent = settings.extendOsmandPath(ResourceManager.MAPS_PATH);
     } else if (i.getType() == LocalIndexType.POI_DATA) {
       parent = settings.extendOsmandPath(ResourceManager.POI_PATH);
     } else if (i.getType() == LocalIndexType.TILES_DATA) {
       parent = settings.extendOsmandPath(ResourceManager.TILES_PATH);
     } else if (i.getType() == LocalIndexType.VOICE_DATA) {
       parent = settings.extendOsmandPath(ResourceManager.VOICE_PATH);
     } else if (i.getType() == LocalIndexType.TTS_VOICE_DATA) {
       parent = settings.extendOsmandPath(ResourceManager.VOICE_PATH);
     }
     return new File(parent, i.getFileName());
   }
   return new File(i.getPathToData());
 }
 private File getFileToBackup(LocalIndexInfo i) {
   if (!i.isBackupedData()) {
     return new File(settings.extendOsmandPath(ResourceManager.BACKUP_PATH), i.getFileName());
   }
   return new File(i.getPathToData());
 }
 private void showContextMenu(final LocalIndexInfo info) {
   Builder builder = new AlertDialog.Builder(this);
   final List<Integer> menu = new ArrayList<Integer>();
   if (info.getType() == LocalIndexType.GPX_DATA) {
     menu.add(R.string.show_gpx_route);
     menu.add(R.string.local_index_mi_upload_gpx);
     descriptionLoader = new LoadLocalIndexDescriptionTask();
     descriptionLoader.execute(info);
   }
   if (info.getType() == LocalIndexType.MAP_DATA || info.getType() == LocalIndexType.POI_DATA) {
     if (!info.isBackupedData()) {
       menu.add(R.string.local_index_mi_backup);
     }
   }
   if (info.isBackupedData()) {
     menu.add(R.string.local_index_mi_restore);
   }
   menu.add(R.string.local_index_mi_rename);
   menu.add(R.string.local_index_mi_delete);
   if (!menu.isEmpty()) {
     String[] values = new String[menu.size()];
     for (int i = 0; i < values.length; i++) {
       values[i] = getString(menu.get(i));
     }
     builder.setItems(
         values,
         new DialogInterface.OnClickListener() {
           @Override
           public void onClick(DialogInterface dialog, int which) {
             int resId = menu.get(which);
             if (resId == R.string.show_gpx_route) {
               if (info != null && info.getGpxFile() != null) {
                 WptPt loc = info.getGpxFile().findPointToShow();
                 if (loc != null) {
                   OsmandSettings settings =
                       OsmandSettings.getOsmandSettings(LocalIndexesActivity.this);
                   settings.setMapLocationToShow(loc.lat, loc.lon, settings.getLastKnownMapZoom());
                 }
                 ((OsmandApplication) getApplication()).setGpxFileToDisplay(info.getGpxFile());
                 MapActivity.launchMapActivityMoveToTop(LocalIndexesActivity.this);
               }
             } else if (resId == R.string.local_index_mi_rename) {
               renameFile(info);
             } else if (resId == R.string.local_index_mi_restore) {
               new LocalIndexOperationTask(RESTORE_OPERATION).execute(info);
             } else if (resId == R.string.local_index_mi_delete) {
               Builder confirm = new AlertDialog.Builder(LocalIndexesActivity.this);
               confirm.setPositiveButton(
                   R.string.default_buttons_yes,
                   new DialogInterface.OnClickListener() {
                     @Override
                     public void onClick(DialogInterface dialog, int which) {
                       new LocalIndexOperationTask(DELETE_OPERATION).execute(info);
                     }
                   });
               confirm.setNegativeButton(R.string.default_buttons_no, null);
               // confirm.setTitle(R.string.delete_confirmation_title);
               confirm.setMessage(getString(R.string.delete_confirmation_msg, info.getFileName()));
               confirm.show();
             } else if (resId == R.string.local_index_mi_backup) {
               new LocalIndexOperationTask(BACKUP_OPERATION).execute(info);
             } else if (resId == R.string.local_index_mi_upload_gpx) {
               Builder confirm = new AlertDialog.Builder(LocalIndexesActivity.this);
               confirm.setPositiveButton(
                   R.string.default_buttons_yes,
                   new DialogInterface.OnClickListener() {
                     @Override
                     public void onClick(DialogInterface dialog, int which) {
                       new UploadGPXFilesTask().execute(info);
                     }
                   });
               confirm.setNegativeButton(R.string.default_buttons_no, null);
               confirm.setMessage(
                   getString(R.string.sendtoOSM_confirmation_msg, info.getFileName()));
               confirm.show();
             }
           }
         });
   }
   builder.show();
 }