use of com.orgzly.android.Book in project orgzly-android by orgzly.
the class MainActivity method onBookDeleteRequest.
/**
* Ask user to confirm, then delete book.
*/
@Override
public void onBookDeleteRequest(final long bookId) {
if (BuildConfig.LOG_DEBUG)
LogUtils.d(TAG, "Get name for the book " + bookId + "...");
final Book book = BooksClient.get(this, bookId);
if (book == null) {
return;
}
View view = View.inflate(this, R.layout.dialog_book_delete, null);
CheckBox checkBox = view.findViewById(R.id.dialog_book_delete_checkbox);
TextView textView = view.findViewById(R.id.dialog_book_delete_text);
checkBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
TypedArray typedArray = obtainStyledAttributes(new int[] { R.attr.text_primary_color, R.attr.text_disabled_color });
int color;
if (isChecked) {
color = typedArray.getColor(0, 0);
} else {
color = typedArray.getColor(1, 0);
}
typedArray.recycle();
textView.setTextColor(color);
});
DialogInterface.OnClickListener dialogClickListener = (dialog, which) -> {
switch(which) {
case DialogInterface.BUTTON_POSITIVE:
boolean deleteLinked = checkBox.isChecked();
/* Delete book. */
mSyncFragment.deleteBook(book, deleteLinked);
break;
case DialogInterface.BUTTON_NEGATIVE:
break;
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this).setTitle(getString(R.string.delete_with_quoted_argument, book.getName())).setPositiveButton(R.string.delete, dialogClickListener).setNegativeButton(R.string.cancel, dialogClickListener);
if (book.getLastSyncedToRook() != null) {
textView.setText(book.getLastSyncedToRook().getUri().toString());
builder.setView(view);
}
builder.show();
}
use of com.orgzly.android.Book in project orgzly-android by orgzly.
the class MainActivity method onBookLinkSetRequest.
@Override
public void onBookLinkSetRequest(final long bookId) {
final Book book = BooksClient.get(this, bookId);
if (book == null) {
return;
}
Map<String, Repo> repos = ReposClient.getAll(this);
if (repos.size() == 0) {
showSnackbarWithReposLink(getString(R.string.no_repos));
return;
}
LinkedHashMap<String, Integer> items = new LinkedHashMap<>();
int itemIndex = 0;
/* Add "no link" item. */
items.put(getString(R.string.no_link), itemIndex++);
/* Add repositories. */
for (String repoUri : repos.keySet()) {
items.put(repoUri, itemIndex++);
}
View view = getLayoutInflater().inflate(R.layout.dialog_spinner, null, false);
final Spinner spinner = (Spinner) view.findViewById(R.id.dialog_spinner);
ArrayAdapter<String> adapter = new ArrayAdapter<>(spinner.getContext(), R.layout.spinner_item, new ArrayList<>(items.keySet()));
adapter.setDropDownViewResource(R.layout.dropdown_item);
spinner.setAdapter(adapter);
/* Set spinner to current book's link. */
if (book.hasLink()) {
Integer pos = items.get(book.getLinkRepo().toString());
if (pos != null) {
spinner.setSelection(pos);
}
}
DialogInterface.OnClickListener dialogClickListener = (dialog, which) -> {
switch(which) {
case DialogInterface.BUTTON_POSITIVE:
Shelf shelf = new Shelf(MainActivity.this);
String repoUrl = (String) spinner.getSelectedItem();
if (getString(R.string.no_link).equals(repoUrl)) {
shelf.setLink(book, null);
} else {
shelf.setLink(book, repoUrl);
}
break;
case DialogInterface.BUTTON_NEGATIVE:
break;
}
};
new AlertDialog.Builder(this).setTitle("Link " + MiscUtils.quotedString(book.getName()) + " to repository").setView(view).setPositiveButton(R.string.set, dialogClickListener).setNegativeButton(R.string.cancel, dialogClickListener).show();
}
use of com.orgzly.android.Book in project orgzly-android by orgzly.
the class MainActivity method setupSearchView.
/**
* SearchView setup and query text listeners.
* TODO: http://developer.android.com/training/search/setup.html
*/
private void setupSearchView(Menu menu) {
final MenuItem searchItem = menu.findItem(R.id.activity_action_search);
final SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setQueryHint(getString(R.string.search_hint));
/* When user starts the search, fill the search box with text depending on current fragment. */
searchView.setOnSearchClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/* Make search as wide as possible. */
ViewGroup.LayoutParams layoutParams = searchView.getLayoutParams();
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
/* For Query fragment, fill the box with full query. */
String q = DisplayManager.getDisplayedQuery(getSupportFragmentManager());
if (q != null) {
searchView.setQuery(q + " ", false);
} else {
/* If searching from book, add book name to query. */
Book book = getActiveFragmentBook();
if (book != null) {
DottedQueryBuilder builder = new DottedQueryBuilder();
String query = builder.build(new Query(new Condition.InBook(book.getName())));
searchView.setQuery(query + " ", false);
}
}
}
});
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextChange(String str) {
return false;
}
@Override
public boolean onQueryTextSubmit(String str) {
if (BuildConfig.LOG_DEBUG)
LogUtils.d(TAG, str);
/* Close search. */
searchItem.collapseActionView();
DisplayManager.displayQuery(getSupportFragmentManager(), str.trim());
return true;
}
});
}
use of com.orgzly.android.Book in project orgzly-android by orgzly.
the class ShareActivity method getDataFromIntent.
public Data getDataFromIntent(Intent intent) {
Data data = new Data();
mError = null;
String action = intent.getAction();
String type = intent.getType();
if (action == null) {
// mError = getString(R.string.share_action_not_set);
} else if (type == null) {
// mError = getString(R.string.share_type_not_set);
} else if (action.equals(Intent.ACTION_SEND)) {
if (type.startsWith("text/")) {
if (intent.hasExtra(Intent.EXTRA_TEXT)) {
data.title = intent.getStringExtra(Intent.EXTRA_TEXT);
} else if (intent.hasExtra(Intent.EXTRA_STREAM)) {
Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
data.title = uri.getLastPathSegment();
/*
* Store file's content as note content.
*/
try {
File file = new File(uri.getPath());
/* Don't read large files. */
if (file.length() > MAX_TEXT_FILE_LENGTH_FOR_CONTENT) {
mError = "File has " + file.length() + " bytes (refusing to read files larger then " + MAX_TEXT_FILE_LENGTH_FOR_CONTENT + " bytes)";
} else {
data.content = MiscUtils.readStringFromFile(file);
}
} catch (IOException e) {
e.printStackTrace();
mError = "Failed reading the content of " + uri.toString() + ": " + e.toString();
}
}
if (data.title != null && data.content == null && intent.hasExtra(Intent.EXTRA_SUBJECT)) {
data.content = data.title;
data.title = intent.getStringExtra(Intent.EXTRA_SUBJECT);
}
if (intent.hasExtra(AppIntent.EXTRA_FILTER)) {
Query query = new DottedQueryParser().parse(intent.getStringExtra(AppIntent.EXTRA_FILTER));
String bookName = QueryUtils.INSTANCE.extractFirstBookNameFromQuery(query.getCondition());
if (bookName != null) {
Book book = new Shelf(this).getBook(bookName);
if (book != null) {
data.bookId = book.getId();
}
}
}
} else {
mError = getString(R.string.share_type_not_supported, type);
}
} else if (action.equals("com.google.android.gm.action.AUTO_SEND")) {
if (type.startsWith("text/") && intent.hasExtra(Intent.EXTRA_TEXT)) {
data.title = intent.getStringExtra(Intent.EXTRA_TEXT);
}
} else {
mError = getString(R.string.share_action_not_supported, action);
}
/* Make sure that title is never empty. */
if (data.title == null) {
data.title = "";
}
return data;
}
use of com.orgzly.android.Book in project orgzly-android by orgzly.
the class BooksFragment method createAdapter.
private SimpleCursorAdapter createAdapter() {
SimpleCursorAdapter adapter;
/* Column field names to be bound. */
String[] columns = { ProviderContract.Books.Param.NAME, ProviderContract.Books.Param.NAME, ProviderContract.Books.Param.MTIME, ProviderContract.Books.Param.LAST_ACTION, ProviderContract.Books.Param.LINK_REPO_URL, ProviderContract.Books.Param.SYNCED_REPO_URL, ProviderContract.Books.Param.SYNCED_ROOK_URL, ProviderContract.Books.Param.SYNCED_ROOK_REVISION, ProviderContract.Books.Param.SYNCED_ROOK_MTIME, ProviderContract.Books.Param.USED_ENCODING, ProviderContract.Books.Param.DETECTED_ENCODING, ProviderContract.Books.Param.SELECTED_ENCODING };
/* Views which the data will be bound to. */
int[] to = { R.id.item_book_title, R.id.item_book_subtitle, R.id.item_book_mtime, R.id.item_book_last_action, R.id.item_book_link_repo, R.id.item_book_synced_repo, R.id.item_book_synced_url, R.id.item_book_synced_revision, R.id.item_book_synced_mtime, R.id.item_book_encoding_used, R.id.item_book_encoding_detected, R.id.item_book_encoding_selected };
adapter = new SimpleCursorAdapter(getActivity(), R.layout.item_book, null, columns, to, 0) {
class ViewHolder {
TextView title;
View modifiedAfterSyncIcon;
View bookDetailsPadding;
View mtimeContainer;
View linkDetailsContainer;
View versionedRookContainer;
View versionedRookUrlContainer;
View versionedRookMtimeContainer;
View versionedRookRevisionContainer;
View lastActionContainer;
View usedEncodingContainer;
View detectedEncodingContainer;
View selectedEncodingContainer;
TextView noteCount;
View noteCountContainer;
TextView lastAction;
TextView subTitle;
TextView mtime;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
super.bindView(view, context, cursor);
ViewHolder holder = (ViewHolder) view.getTag();
if (holder == null) {
holder = new ViewHolder();
holder.title = view.findViewById(R.id.item_book_title);
holder.modifiedAfterSyncIcon = view.findViewById(R.id.item_book_modified_after_sync_icon);
holder.bookDetailsPadding = view.findViewById(R.id.item_book_details_padding);
holder.subTitle = view.findViewById(R.id.item_book_subtitle);
holder.mtimeContainer = view.findViewById(R.id.item_book_mtime_container);
holder.mtime = view.findViewById(R.id.item_book_mtime);
holder.linkDetailsContainer = view.findViewById(R.id.item_book_link_container);
holder.versionedRookContainer = view.findViewById(R.id.item_book_synced_container);
holder.versionedRookUrlContainer = view.findViewById(R.id.item_book_synced_url_container);
holder.versionedRookMtimeContainer = view.findViewById(R.id.item_book_synced_mtime_container);
holder.versionedRookRevisionContainer = view.findViewById(R.id.item_book_synced_revision_container);
holder.lastActionContainer = view.findViewById(R.id.item_book_last_action_container);
holder.lastAction = view.findViewById(R.id.item_book_last_action);
holder.usedEncodingContainer = view.findViewById(R.id.item_book_encoding_used_container);
holder.detectedEncodingContainer = view.findViewById(R.id.item_book_encoding_detected_container);
holder.selectedEncodingContainer = view.findViewById(R.id.item_book_encoding_selected_container);
holder.noteCount = view.findViewById(R.id.item_book_note_count);
holder.noteCountContainer = view.findViewById(R.id.item_book_note_count_container);
view.setTag(holder);
}
Book book = BooksClient.fromCursor(cursor);
/*
* If title exists - use title and set book's name as a subtitle.
* If title does no exist - use book's name hide the subtitle.
*/
if (book.getOrgFileSettings().getTitle() != null) {
holder.title.setText(book.getOrgFileSettings().getTitle());
holder.subTitle.setText(book.getName());
holder.subTitle.setVisibility(View.VISIBLE);
} else {
holder.title.setText(book.getName());
holder.subTitle.setVisibility(View.GONE);
}
if (book.isModifiedAfterLastSync()) {
holder.modifiedAfterSyncIcon.setVisibility(View.VISIBLE);
} else {
holder.modifiedAfterSyncIcon.setVisibility(View.INVISIBLE);
}
/*
* Modification time.
*/
ElementPlacer placer = new ElementPlacer();
placer.displayDetailByCondition(holder.mtimeContainer, isPreferenceActivated(R.string.pref_value_book_details_mtime, context));
/* If book has no link - remove related rows. */
if (book.hasLink()) {
placer.displayDetailByCondition(holder.linkDetailsContainer, isPreferenceActivated(R.string.pref_value_book_details_link_url, context));
} else {
placer.hideElement(holder.linkDetailsContainer);
}
/* If book has no versioned rook - remove all related rows. */
if (book.getLastSyncedToRook() != null) {
placer.showElement(holder.versionedRookContainer);
placer.displayDetailByCondition(holder.versionedRookUrlContainer, isPreferenceActivated(R.string.pref_value_book_details_sync_url, context));
placer.displayDetailByCondition(holder.versionedRookMtimeContainer, isPreferenceActivated(R.string.pref_value_book_details_sync_mtime, context));
placer.displayDetailByCondition(holder.versionedRookRevisionContainer, isPreferenceActivated(R.string.pref_value_book_details_sync_revision, context));
} else {
placer.hideElement(holder.versionedRookContainer);
}
/* Hide last action if
* - there is no last action (sync) performed
* OR
* - action is INFO but user choose not to display it
*/
boolean shouldHideLastAction = book.getLastAction() == null || (lastActionWasInfo(book) && !isPreferenceActivated(R.string.pref_value_book_details_last_action, context));
placer.displayDetailByCondition(holder.lastActionContainer, !shouldHideLastAction);
if (!shouldHideLastAction) {
holder.lastAction.setText(getLastActionText(book));
}
/*
* Display encodings if set.
*/
boolean shouldShowSelectedEncoding = book.getSelectedEncoding() != null && isPreferenceActivated(R.string.pref_value_book_details_encoding_selected, context);
placer.displayDetailByCondition(holder.selectedEncodingContainer, shouldShowSelectedEncoding);
boolean shouldShowDetectedEncoding = book.getDetectedEncoding() != null && isPreferenceActivated(R.string.pref_value_book_details_encoding_detected, context);
placer.displayDetailByCondition(holder.detectedEncodingContainer, shouldShowDetectedEncoding);
boolean shouldShowUsedEncoding = book.getUsedEncoding() != null && isPreferenceActivated(R.string.pref_value_book_details_encoding_used, context);
placer.displayDetailByCondition(holder.usedEncodingContainer, shouldShowUsedEncoding);
/* If it's a dummy book - change opacity. */
if (book.isDummy()) {
view.setAlpha(0.4f);
} else {
view.setAlpha(1);
}
placer.displayDetailByCondition(holder.noteCountContainer, isPreferenceActivated(R.string.pref_value_book_details_notes_count, context));
/* Set notes count. For some reason, there are crashes reported here and there
* for some users if NOTES_COUNT is included in SimpleCursorAdapter's column list.
*/
int noteCount = cursor.getInt(cursor.getColumnIndexOrThrow(DbBookViewColumns.NOTES_COUNT));
holder.noteCount.setText(noteCount > 0 ? getResources().getQuantityString(R.plurals.notes_count_nonzero, noteCount, noteCount) : getString(R.string.notes_count_zero));
/*
* Add some vertical spacing if at least one of the notebook details is displayed.
*/
placer.displayElementByCondition(holder.bookDetailsPadding, placer.anyDetailWasShown());
}
class ElementPlacer {
private boolean detailWasShown = false;
private void displayElementByCondition(View element, boolean condition) {
element.setVisibility(condition ? View.VISIBLE : View.GONE);
}
private void displayDetailByCondition(View detail, boolean condition) {
displayElementByCondition(detail, condition);
if (condition) {
detailWasShown = true;
}
}
private void showElement(View element) {
element.setVisibility(View.VISIBLE);
}
private void hideElement(View element) {
element.setVisibility(View.GONE);
}
boolean anyDetailWasShown() {
return detailWasShown;
}
}
private boolean isPreferenceActivated(int preferenceCode, Context context) {
return AppPreferences.displayedBookDetails(context).contains(getString(preferenceCode));
}
private boolean lastActionWasInfo(Book book) {
return book.getLastAction().getType() == BookAction.Type.INFO;
}
private CharSequence getLastActionText(Book book) {
SpannableStringBuilder builder = new SpannableStringBuilder();
builder.append(timeString(book.getLastAction().getTimestamp()));
builder.append(": ");
int pos = builder.length();
builder.append(book.getLastAction().getMessage());
if (book.getLastAction().getType() == BookAction.Type.ERROR) {
/* Get error color attribute. */
TypedArray arr = getActivity().obtainStyledAttributes(new int[] { R.attr.text_error_color });
int color = arr.getColor(0, 0);
arr.recycle();
/* Set error color. */
builder.setSpan(new ForegroundColorSpan(color), pos, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (book.getLastAction().getType() == BookAction.Type.PROGRESS) {
builder.setSpan(new StyleSpan(Typeface.BOLD), pos, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
return builder;
}
};
adapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
@Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
boolean hasData = !cursor.isNull(columnIndex);
String viewContent = null;
switch(view.getId()) {
case R.id.item_book_encoding_used:
if (hasData) {
viewContent = cursor.getString(columnIndex) + " used";
}
break;
case R.id.item_book_encoding_detected:
if (hasData) {
viewContent = cursor.getString(columnIndex) + " detected";
}
break;
case R.id.item_book_encoding_selected:
if (hasData) {
viewContent = cursor.getString(columnIndex) + " selected";
}
break;
/* Generic N/A-if-does-not-exist. */
case R.id.item_book_synced_revision:
if (hasData) {
viewContent = cursor.getString(columnIndex);
} else {
viewContent = "N/A";
}
break;
case R.id.item_book_synced_mtime:
if (hasData && cursor.getLong(columnIndex) > 0) {
/* Format time. */
viewContent = timeString(cursor.getLong(columnIndex));
} else {
viewContent = "N/A";
}
break;
case R.id.item_book_mtime:
if (hasData && cursor.getLong(columnIndex) > 0) {
/* Format time. */
viewContent = timeString(cursor.getLong(columnIndex));
} else {
viewContent = getString(R.string.book_never_modified_locally);
}
break;
case R.id.item_book_link_repo:
case R.id.item_book_synced_url:
if (hasData) {
viewContent = cursor.getString(columnIndex);
}
break;
default:
return false;
}
if (viewContent != null) {
((TextView) view).setText(viewContent);
}
return true;
}
});
return adapter;
}
Aggregations