/**
   * Color of category marker if note is categorized a function is active in preferences
   *
   * @param note
   * @param rowView
   */
  private void colorNote(Note note, View v, NoteAdapterViewHolder holder) {

    String colorsPref =
        mActivity
            .getSharedPreferences(Constants.PREFS_NAME, mActivity.MODE_MULTI_PROCESS)
            .getString("settings_colors_app", Constants.PREF_COLORS_APP_DEFAULT);

    // Checking preference
    if (!colorsPref.equals("disabled")) {

      // Resetting transparent color to the view
      v.setBackgroundColor(Color.parseColor("#00000000"));

      // If category is set the color will be applied on the appropriate target
      if (note.getCategory() != null && note.getCategory().getColor() != null) {
        if (colorsPref.equals("complete") || colorsPref.equals("list")) {
          v.setBackgroundColor(Integer.parseInt(note.getCategory().getColor()));
        } else {
          if (holder != null) {
            holder.categoryMarker.setBackgroundColor(
                Integer.parseInt(note.getCategory().getColor()));
          } else {
            v.findViewById(R.id.category_marker)
                .setBackgroundColor(Integer.parseInt(note.getCategory().getColor()));
          }
        }
      } else {
        v.findViewById(R.id.category_marker).setBackgroundColor(0);
      }
    }
  }
  /**
   * Choosing which date must be shown depending on sorting criteria
   *
   * @return String ith formatted date
   */
  public static String getDateText(Context mContext, Note note) {
    String dateText;
    SharedPreferences prefs =
        mContext.getSharedPreferences(Constants.PREFS_NAME, mContext.MODE_MULTI_PROCESS);
    String sort_column = prefs.getString(Constants.PREF_SORTING_COLUMN, "");

    // Creation
    if (sort_column.equals(DbHelper.KEY_CREATION)) {
      dateText = mContext.getString(R.string.creation) + " " + note.getCreationShort(mContext);
    }
    // Reminder
    else if (sort_column.equals(DbHelper.KEY_ALARM)) {
      String alarmShort = note.getAlarmShort(mContext);

      if (alarmShort.length() == 0) {
        dateText = mContext.getString(R.string.no_reminder_set);
      } else {
        dateText = mContext.getString(R.string.alarm_set_on) + " " + note.getAlarmShort(mContext);
      }
    }
    // Others
    else {
      dateText =
          mContext.getString(R.string.last_update) + " " + note.getLastModificationShort(mContext);
    }
    return dateText;
  }
 /** Used to perform a quick text-only note saving (eg. Tasker+Pushbullet) */
 private void saveAndExit(Intent i) {
   Note note = new Note();
   note.setTitle(i.getStringExtra(Intent.EXTRA_SUBJECT));
   note.setContent(i.getStringExtra(Intent.EXTRA_TEXT));
   DbHelper.getInstance(this).updateNote(note, true);
   showToast(getString(R.string.note_updated), Toast.LENGTH_SHORT);
   finish();
 }
 private boolean noteAlreadyOpened(Note note) {
   DetailFragment detailFragment =
       (DetailFragment) mFragmentManager.findFragmentByTag(FRAGMENT_DETAIL_TAG);
   return detailFragment != null
       && detailFragment.getCurrentNote() != null
       && detailFragment.getCurrentNote().get_id() == note.get_id();
 }
 /**
  * Single note permanent deletion
  *
  * @param note Note to be deleted
  */
 @SuppressLint("NewApi")
 public void deleteNote(Note note) {
   // Saving changes to the note
   DeleteNoteTask deleteNoteTask = new DeleteNoteTask(getApplicationContext());
   deleteNoteTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, note);
   // Informs about update
   Ln.d("Deleted permanently note with id '" + note.get_id() + "'");
 }
Exemple #6
0
 /** Deleting single note but keeping attachments */
 public boolean deleteNote(Note note, boolean keepAttachments) {
   int deletedNotes;
   boolean result = true;
   SQLiteDatabase db = getDatabase(true);
   // Delete notes
   deletedNotes =
       db.delete(TABLE_NOTES, KEY_ID + " = ?", new String[] {String.valueOf(note.get_id())});
   if (!keepAttachments) {
     // Delete note's attachments
     int deletedAttachments =
         db.delete(
             TABLE_ATTACHMENTS,
             KEY_ATTACHMENT_NOTE_ID + " = ?",
             new String[] {String.valueOf(note.get_id())});
     result = result && deletedAttachments == note.getAttachmentsList().size();
   }
   // Check on correct and complete deletion
   result = result && deletedNotes == 1;
   return result;
 }
  /** Notes sharing */
  public void shareNote(Note note) {

    String titleText = note.getTitle();

    String contentText = titleText + System.getProperty("line.separator") + note.getContent();

    Intent shareIntent = new Intent();
    // Prepare sharing intent with only text
    if (note.getAttachmentsList().size() == 0) {
      shareIntent.setAction(Intent.ACTION_SEND);
      shareIntent.setType("text/plain");
      shareIntent.putExtra(Intent.EXTRA_SUBJECT, titleText);
      shareIntent.putExtra(Intent.EXTRA_TEXT, contentText);

      // Intent with single image attachment
    } else if (note.getAttachmentsList().size() == 1) {
      shareIntent.setAction(Intent.ACTION_SEND);
      shareIntent.setType(note.getAttachmentsList().get(0).getMime_type());
      shareIntent.putExtra(Intent.EXTRA_STREAM, note.getAttachmentsList().get(0).getUri());
      shareIntent.putExtra(Intent.EXTRA_SUBJECT, titleText);
      shareIntent.putExtra(Intent.EXTRA_TEXT, contentText);

      // Intent with multiple images
    } else if (note.getAttachmentsList().size() > 1) {
      shareIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
      ArrayList<Uri> uris = new ArrayList<>();
      // A check to decide the mime type of attachments to share is done here
      HashMap<String, Boolean> mimeTypes = new HashMap<>();
      for (Attachment attachment : note.getAttachmentsList()) {
        uris.add(attachment.getUri());
        mimeTypes.put(attachment.getMime_type(), true);
      }
      // If many mime types are present a general type is assigned to intent
      if (mimeTypes.size() > 1) {
        shareIntent.setType("*/*");
      } else {
        shareIntent.setType((String) mimeTypes.keySet().toArray()[0]);
      }

      shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
      shareIntent.putExtra(Intent.EXTRA_SUBJECT, titleText);
      shareIntent.putExtra(Intent.EXTRA_TEXT, contentText);
    }

    startActivity(
        Intent.createChooser(
            shareIntent, getResources().getString(R.string.share_message_chooser)));
  }
Exemple #8
0
 /** Counts words in a note */
 public int getWords(Note note) {
   int count = 0;
   String[] fields = {note.getTitle(), note.getContent()};
   for (String field : fields) {
     boolean word = false;
     int endOfLine = field.length() - 1;
     for (int i = 0; i < field.length(); i++) {
       // if the char is a letter, word = true.
       if (Character.isLetter(field.charAt(i)) && i != endOfLine) {
         word = true;
         // if char isn't a letter and there have been letters before,
         // counter goes up.
       } else if (!Character.isLetter(field.charAt(i)) && word) {
         count++;
         word = false;
         // last word of String; if it doesn't end with a non letter, it
         // wouldn't count without this.
       } else if (Character.isLetter(field.charAt(i)) && i == endOfLine) {
         count++;
       }
     }
   }
   return count;
 }
Exemple #9
0
  /** Retrieves all tags of a specified note */
  public List<Tag> getTags(Note note) {
    List<Tag> tags = new ArrayList<>();
    HashMap<String, Integer> tagsMap = new HashMap<>();

    String whereCondition =
        " WHERE "
            + (note != null ? KEY_ID + " = " + note.get_id() + " AND " : "")
            + "("
            + KEY_CONTENT
            + " LIKE '%#%' OR "
            + KEY_TITLE
            + " LIKE '%#%' "
            + ")"
            + " AND "
            + KEY_TRASHED
            + " IS "
            + (Navigation.checkNavigation(Navigation.TRASH) ? "" : " NOT ")
            + " 1";
    List<Note> notesRetrieved = getNotes(whereCondition, true);

    for (Note noteRetrieved : notesRetrieved) {
      HashMap<String, Integer> tagsRetrieved = TagsHelper.retrieveTags(noteRetrieved);
      for (String s : tagsRetrieved.keySet()) {
        int count = tagsMap.get(s) == null ? 0 : tagsMap.get(s);
        tagsMap.put(s, ++count);
      }
    }

    for (String s : tagsMap.keySet()) {
      Tag tag = new Tag(s, tagsMap.get(s));
      tags.add(tag);
    }

    Collections.sort(tags, (tag1, tag2) -> tag1.getText().compareToIgnoreCase(tag2.getText()));
    return tags;
  }
Exemple #10
0
  // Inserting or updating single note
  public Note updateNote(Note note, boolean updateLastModification) {
    SQLiteDatabase db = getDatabase(true);

    String content;
    if (note.isLocked()) {
      content = Security.encrypt(note.getContent(), prefs.getString(Constants.PREF_PASSWORD, ""));
    } else {
      content = note.getContent();
    }

    // To ensure note and attachments insertions are atomical and boost performances transaction are
    // used
    db.beginTransaction();

    ContentValues values = new ContentValues();
    values.put(KEY_TITLE, note.getTitle());
    values.put(KEY_CONTENT, content);
    values.put(
        KEY_CREATION,
        note.getCreation() != null ? note.getCreation() : Calendar.getInstance().getTimeInMillis());
    values.put(
        KEY_LAST_MODIFICATION,
        updateLastModification
            ? Calendar.getInstance().getTimeInMillis()
            : (note.getLastModification() != null
                ? note.getLastModification()
                : Calendar.getInstance().getTimeInMillis()));
    values.put(KEY_ARCHIVED, note.isArchived());
    values.put(KEY_TRASHED, note.isTrashed());
    values.put(KEY_REMINDER, note.getAlarm());
    values.put(KEY_REMINDER_FIRED, note.isReminderFired());
    values.put(KEY_RECURRENCE_RULE, note.getRecurrenceRule());
    values.put(KEY_LATITUDE, note.getLatitude());
    values.put(KEY_LONGITUDE, note.getLongitude());
    values.put(KEY_ADDRESS, note.getAddress());
    values.put(KEY_CATEGORY, note.getCategory() != null ? note.getCategory().getId() : null);
    boolean locked = note.isLocked() != null ? note.isLocked() : false;
    values.put(KEY_LOCKED, locked);
    boolean checklist = note.isChecklist() != null ? note.isChecklist() : false;
    values.put(KEY_CHECKLIST, checklist);

    db.insertWithOnConflict(TABLE_NOTES, KEY_ID, values, SQLiteDatabase.CONFLICT_REPLACE);
    Log.d(Constants.TAG, "Updated note titled '" + note.getTitle() + "'");

    // Updating attachments
    List<Attachment> deletedAttachments = note.getAttachmentsListOld();
    for (Attachment attachment : note.getAttachmentsList()) {
      updateAttachment(
          note.get_id() != null ? note.get_id() : values.getAsLong(KEY_CREATION), attachment, db);
      deletedAttachments.remove(attachment);
    }
    // Remove from database deleted attachments
    for (Attachment attachmentDeleted : deletedAttachments) {
      db.delete(
          TABLE_ATTACHMENTS,
          KEY_ATTACHMENT_ID + " = ?",
          new String[] {String.valueOf(attachmentDeleted.getId())});
    }

    db.setTransactionSuccessful();
    db.endTransaction();

    // Fill the note with correct data before returning it
    note.setCreation(
        note.getCreation() != null ? note.getCreation() : values.getAsLong(KEY_CREATION));
    note.setLastModification(values.getAsLong(KEY_LAST_MODIFICATION));

    return note;
  }
Exemple #11
0
 /** Trashes/restore single note */
 public void trashNote(Note note, boolean trash) {
   note.setTrashed(trash);
   updateNote(note, false);
 }
Exemple #12
0
 /** Archives/restore single note */
 public void archiveNote(Note note, boolean archive) {
   note.setArchived(archive);
   updateNote(note, false);
 }
Exemple #13
0
  /**
   * Common method for notes retrieval. It accepts a query to perform and returns matching records.
   */
  public List<Note> getNotes(String whereCondition, boolean order) {
    List<Note> noteList = new ArrayList<>();

    String sort_column, sort_order = "";

    // Getting sorting criteria from preferences. Reminder screen forces sorting.
    if (Navigation.checkNavigation(Navigation.REMINDERS)) {
      sort_column = KEY_REMINDER;
    } else {
      sort_column = prefs.getString(Constants.PREF_SORTING_COLUMN, KEY_TITLE);
    }
    if (order) {
      sort_order =
          KEY_TITLE.equals(sort_column) || KEY_REMINDER.equals(sort_column) ? " ASC " : " DESC ";
    }

    // In case of title sorting criteria it must be handled empty title by concatenating content
    sort_column = KEY_TITLE.equals(sort_column) ? KEY_TITLE + "||" + KEY_CONTENT : sort_column;

    // In case of reminder sorting criteria the empty reminder notes must be moved on bottom of
    // results
    sort_column =
        KEY_REMINDER.equals(sort_column)
            ? "IFNULL(" + KEY_REMINDER + ", " + "" + Constants.TIMESTAMP_UNIX_EPOCH + ")"
            : sort_column;

    // Generic query to be specialized with conditions passed as parameter
    String query =
        "SELECT "
            + KEY_CREATION
            + ","
            + KEY_LAST_MODIFICATION
            + ","
            + KEY_TITLE
            + ","
            + KEY_CONTENT
            + ","
            + KEY_ARCHIVED
            + ","
            + KEY_TRASHED
            + ","
            + KEY_REMINDER
            + ","
            + KEY_REMINDER_FIRED
            + ","
            + KEY_RECURRENCE_RULE
            + ","
            + KEY_LATITUDE
            + ","
            + KEY_LONGITUDE
            + ","
            + KEY_ADDRESS
            + ","
            + KEY_LOCKED
            + ","
            + KEY_CHECKLIST
            + ","
            + KEY_CATEGORY
            + ","
            + KEY_CATEGORY_NAME
            + ","
            + KEY_CATEGORY_DESCRIPTION
            + ","
            + KEY_CATEGORY_COLOR
            + " FROM "
            + TABLE_NOTES
            + " LEFT JOIN "
            + TABLE_CATEGORY
            + " USING( "
            + KEY_CATEGORY
            + ") "
            + whereCondition
            + (order ? " ORDER BY " + sort_column + sort_order : "");

    Log.v(Constants.TAG, "Query: " + query);

    Cursor cursor = null;
    try {
      cursor = getDatabase().rawQuery(query, null);

      // Looping through all rows and adding to list
      if (cursor.moveToFirst()) {
        do {
          int i = 0;
          Note note = new Note();
          note.setCreation(cursor.getLong(i++));
          note.setLastModification(cursor.getLong(i++));
          note.setTitle(cursor.getString(i++));
          note.setContent(cursor.getString(i++));
          note.setArchived("1".equals(cursor.getString(i++)));
          note.setTrashed("1".equals(cursor.getString(i++)));
          note.setAlarm(cursor.getString(i++));
          note.setReminderFired(cursor.getInt(i++));
          note.setRecurrenceRule(cursor.getString(i++));
          note.setLatitude(cursor.getString(i++));
          note.setLongitude(cursor.getString(i++));
          note.setAddress(cursor.getString(i++));
          note.setLocked("1".equals(cursor.getString(i++)));
          note.setChecklist("1".equals(cursor.getString(i++)));

          // Eventual decryption of content
          if (note.isLocked()) {
            note.setContent(
                Security.decrypt(note.getContent(), prefs.getString(Constants.PREF_PASSWORD, "")));
          }

          // Set category
          long categoryId = cursor.getLong(i++);
          if (categoryId != 0) {
            Category category =
                new Category(
                    categoryId,
                    cursor.getString(i++),
                    cursor.getString(i++),
                    cursor.getString(i++));
            note.setCategory(category);
          }

          // Add eventual attachments uri
          note.setAttachmentsList(getNoteAttachments(note));

          // Adding note to list
          noteList.add(note);

        } while (cursor.moveToNext());
      }

    } finally {
      if (cursor != null) cursor.close();
    }

    Log.v(Constants.TAG, "Query: Retrieval finished!");
    return noteList;
  }
Exemple #14
0
 /** Counts chars in a note */
 public int getChars(Note note) {
   int count = 0;
   count += note.getTitle().length();
   count += note.getContent().length();
   return count;
 }
Exemple #15
0
 /** Retrieves all attachments related to specific note */
 public ArrayList<Attachment> getNoteAttachments(Note note) {
   String whereCondition = " WHERE " + KEY_ATTACHMENT_NOTE_ID + " = " + note.get_id();
   return getAttachments(whereCondition);
 }
  @SuppressLint("NewApi")
  @Override
  public View getView(int position, View convertView, ViewGroup parent) {

    Note note = notes.get(position);

    NoteAdapterViewHolder holder;
    if (convertView == null) {
      convertView = inflater.inflate(layout, parent, false);

      // Overrides font sizes with the one selected from user
      Fonts.overrideTextSize(
          mActivity,
          mActivity.getSharedPreferences(Constants.PREFS_NAME, Context.MODE_MULTI_PROCESS),
          convertView);

      holder = new NoteAdapterViewHolder();

      holder.root = convertView.findViewById(R.id.root);
      holder.cardLayout = convertView.findViewById(R.id.card_layout);
      holder.categoryMarker = convertView.findViewById(R.id.category_marker);

      holder.title = (TextView) convertView.findViewById(R.id.note_title);
      holder.content = (TextView) convertView.findViewById(R.id.note_content);
      holder.date = (TextView) convertView.findViewById(R.id.note_date);

      holder.archiveIcon = (ImageView) convertView.findViewById(R.id.archivedIcon);
      //	    	holder.trashIcon = (ImageView) convertView.findViewById(R.id.trashedIcon);
      holder.locationIcon = (ImageView) convertView.findViewById(R.id.locationIcon);
      holder.alarmIcon = (ImageView) convertView.findViewById(R.id.alarmIcon);
      holder.lockedIcon = (ImageView) convertView.findViewById(R.id.lockedIcon);
      if (!expandedView)
        holder.attachmentIcon = (ImageView) convertView.findViewById(R.id.attachmentIcon);

      holder.attachmentThumbnail =
          (SquareImageView) convertView.findViewById(R.id.attachmentThumbnail);

      convertView.setTag(holder);

    } else {
      holder = (NoteAdapterViewHolder) convertView.getTag();
    }

    try {
      //			if (note.isChecklist()) {
      TextWorkerTask task =
          new TextWorkerTask(mActivity, holder.title, holder.content, expandedView);
      if (Build.VERSION.SDK_INT >= 11) {
        task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, note);
      } else {
        task.execute(note);
      }
      //			} else {
      //				Spanned[] titleAndContent = TextHelper.parseTitleAndContent(mActivity, note);
      //				holder.title.setText(titleAndContent[0]);
      //				holder.content.setText(titleAndContent[1]);
      //			}
    } catch (RejectedExecutionException e) {
      Log.w(Constants.TAG, "Oversized tasks pool to load texts!");
    }

    // Evaluates the archived state...
    holder.archiveIcon.setVisibility(note.isArchived() ? View.VISIBLE : View.GONE);
    // .. the trashed state
    //		holder.trashIcon.setVisibility(note.isTrashed() ? View.VISIBLE : View.GONE);
    // ...the location
    holder.locationIcon.setVisibility(
        note.getLongitude() != null && note.getLongitude() != 0 ? View.VISIBLE : View.GONE);
    // ...the presence of an alarm
    holder.alarmIcon.setVisibility(note.getAlarm() != null ? View.VISIBLE : View.GONE);
    // ...the locked with password state
    holder.lockedIcon.setVisibility(note.isLocked() ? View.VISIBLE : View.GONE);
    // ...the attachment icon for contracted view
    if (!expandedView) {
      holder.attachmentIcon.setVisibility(
          note.getAttachmentsList().size() > 0 ? View.VISIBLE : View.GONE);
    }

    String dateText = getDateText(mActivity, note);
    holder.date.setText(dateText);

    // Highlighted if is part of multiselection of notes. Remember to search for child with card ui
    if (selectedItems.get(position)) {
      holder.cardLayout.setBackgroundColor(
          mActivity.getResources().getColor(R.color.list_bg_selected));
    } else {
      restoreDrawable(note, holder.cardLayout, holder);
    }

    // Attachment thumbnail
    if (expandedView) {
      // If note is locked or without attachments nothing is shown
      if ((note.isLocked()
              && !mActivity
                  .getSharedPreferences(Constants.PREFS_NAME, mActivity.MODE_MULTI_PROCESS)
                  .getBoolean("settings_password_access", false))
          || note.getAttachmentsList().size() == 0) {
        holder.attachmentThumbnail.setImageResource(0);
        holder.attachmentThumbnail.setVisibility(View.GONE);
      }
      // Otherwise...
      else {
        Attachment mAttachment = note.getAttachmentsList().get(0);
        loadThumbnail(holder, mAttachment);
      }
    }

    //		Animation animation = AnimationUtils.loadAnimation(mActivity, R.animator.fade_in);
    //		animation.setDuration(60);
    //		convertView.startAnimation(animation);

    return convertView;
  }
Exemple #17
0
  /** Retrieves statistics data based on app usage */
  public Stats getStats() {
    Stats mStats = new Stats();

    // Categories
    mStats.setCategories(getCategories().size());

    // Everything about notes and their text stats
    int notesActive = 0,
        notesArchived = 0,
        notesTrashed = 0,
        reminders = 0,
        remindersFuture = 0,
        checklists = 0,
        notesMasked = 0,
        tags = 0,
        locations = 0;
    int totalWords = 0, totalChars = 0, maxWords = 0, maxChars = 0, avgWords = 0, avgChars = 0;
    int words, chars;
    List<Note> notes = getAllNotes(false);
    for (Note note : notes) {
      if (note.isTrashed()) {
        notesTrashed++;
      } else if (note.isArchived()) {
        notesArchived++;
      } else {
        notesActive++;
      }
      if (note.getAlarm() != null && Long.parseLong(note.getAlarm()) > 0) {
        if (Long.parseLong(note.getAlarm()) > Calendar.getInstance().getTimeInMillis()) {
          remindersFuture++;
        } else {
          reminders++;
        }
      }
      if (note.isChecklist()) {
        checklists++;
      }
      if (note.isLocked()) {
        notesMasked++;
      }
      tags += TagsHelper.retrieveTags(note).size();
      if (note.getLongitude() != null && note.getLongitude() != 0) {
        locations++;
      }
      words = getWords(note);
      chars = getChars(note);
      if (words > maxWords) {
        maxWords = words;
      }
      if (chars > maxChars) {
        maxChars = chars;
      }
      totalWords += words;
      totalChars += chars;
    }
    mStats.setNotesActive(notesActive);
    mStats.setNotesArchived(notesArchived);
    mStats.setNotesTrashed(notesTrashed);
    mStats.setReminders(reminders);
    mStats.setRemindersFutures(remindersFuture);
    mStats.setNotesChecklist(checklists);
    mStats.setNotesMasked(notesMasked);
    mStats.setTags(tags);
    mStats.setLocation(locations);
    avgWords = totalWords / (notes.size() != 0 ? notes.size() : 1);
    avgChars = totalChars / (notes.size() != 0 ? notes.size() : 1);

    mStats.setWords(totalWords);
    mStats.setWordsMax(maxWords);
    mStats.setWordsAvg(avgWords);
    mStats.setChars(totalChars);
    mStats.setCharsMax(maxChars);
    mStats.setCharsAvg(avgChars);

    // Everything about attachments
    int attachmentsAll = 0, images = 0, videos = 0, audioRecordings = 0, sketches = 0, files = 0;
    List<Attachment> attachments = getAllAttachments();
    for (Attachment attachment : attachments) {
      if (Constants.MIME_TYPE_IMAGE.equals(attachment.getMime_type())) {
        images++;
      } else if (Constants.MIME_TYPE_VIDEO.equals(attachment.getMime_type())) {
        videos++;
      } else if (Constants.MIME_TYPE_AUDIO.equals(attachment.getMime_type())) {
        audioRecordings++;
      } else if (Constants.MIME_TYPE_SKETCH.equals(attachment.getMime_type())) {
        sketches++;
      } else if (Constants.MIME_TYPE_FILES.equals(attachment.getMime_type())) {
        files++;
      }
    }
    mStats.setAttachments(attachmentsAll);
    mStats.setImages(images);
    mStats.setVideos(videos);
    mStats.setAudioRecordings(audioRecordings);
    mStats.setSketches(sketches);
    mStats.setFiles(files);

    return mStats;
  }