/** * 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() + "'"); }
/** 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))); }
/** 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; }
/** 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; }
// 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; }
/** Trashes/restore single note */ public void trashNote(Note note, boolean trash) { note.setTrashed(trash); updateNote(note, false); }
/** Archives/restore single note */ public void archiveNote(Note note, boolean archive) { note.setArchived(archive); updateNote(note, false); }
/** * 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; }
/** Counts chars in a note */ public int getChars(Note note) { int count = 0; count += note.getTitle().length(); count += note.getContent().length(); return count; }
/** 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; }
/** 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; }