package com.jbirdvegas.mgerrit.cards; /* * Copyright (C) 2013 Android Open Kang Project (AOKP) * Author: Jon Stanford (JBirdVegas), 2013 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseExpandableListAdapter; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.ExpandableListView; import android.widget.TextView; import com.jbirdvegas.mgerrit.DiffViewer; import com.jbirdvegas.mgerrit.Prefs; import com.jbirdvegas.mgerrit.R; import com.jbirdvegas.mgerrit.adapters.CommitDetailsAdapter; import com.jbirdvegas.mgerrit.database.Config; import com.jbirdvegas.mgerrit.database.FileChanges; import com.jbirdvegas.mgerrit.objects.FileInfo; public class PatchSetChangesCard implements CardBinder { private final Context mContext; private final LayoutInflater mInflater; // Colors private final int mGreen; private final int mRed; // The theme we are using, so we can get the default text color private final boolean mUsingLightTheme; // Cursor indices private Integer mChangeId_index; private Integer mFileName_index; private Integer mStatus_index; private Integer mIsBinary_index; private Integer mOldPath_index; private Integer mInserted_index; private Integer mDeleted_index; private Integer mPatchSet_index; private Integer mCommit_index; private Integer mIsImage_index; public PatchSetChangesCard(Context context) { mContext = context; mGreen = context.getResources().getColor(R.color.text_green); mRed = context.getResources().getColor(R.color.text_red); mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mUsingLightTheme = (Prefs.getCurrentThemeID(mContext) == R.style.Theme_Light); } @Override public View setViewValue(Cursor cursor, View convertView, ViewGroup parent) { if (convertView == null) { convertView = mInflater.inflate(R.layout.patchset_changes_card, parent, false); } ViewHolder viewHolder = (ViewHolder) convertView.getTag(); if (viewHolder == null) { viewHolder = new ViewHolder(convertView); convertView.setTag(viewHolder); } setupCusorIndicies(cursor); // we always have a path viewHolder.path.setText(cursor.getString(mFileName_index)); FileInfo.Status status = FileInfo.Status.getValue(cursor.getString(mStatus_index)); if (status == FileInfo.Status.ADDED) { viewHolder.path.setTextColor(mGreen); } else if (status == FileInfo.Status.DELETED) { viewHolder.path.setTextColor(mRed); } else { // Need to determine from the current theme what the default color is and set it back if (mUsingLightTheme) { viewHolder.path.setTextColor(mContext.getResources().getColor(R.color.text_light)); } else { viewHolder.path.setTextColor(mContext.getResources().getColor(R.color.text_dark)); } } String oldPath = cursor.getString(mOldPath_index); if (oldPath != null && !oldPath.isEmpty()) { viewHolder.oldPathContainer.setVisibility(View.VISIBLE); viewHolder.oldPath.setText(oldPath); } else { viewHolder.oldPathContainer.setVisibility(View.GONE); } int insertedInFile = cursor.getInt(mInserted_index); int deletedInFile = cursor.getInt(mDeleted_index); // we may not have inserted lines so remove if unneeded if (insertedInFile < 1) { viewHolder.insText.setVisibility(View.GONE); } else { viewHolder.insText.setVisibility(View.VISIBLE); viewHolder.inserted.setText('+' + String.valueOf(insertedInFile)); } // we may not have deleted lines so remove if unneeded if (deletedInFile < 1) { viewHolder.delText.setVisibility(View.GONE); } else { viewHolder.delText.setVisibility(View.VISIBLE); viewHolder.deleted.setText('-' + String.valueOf(deletedInFile)); } /* If the file is binary don't offer to show the diff as * we cannot get detailed information on binary files */ if (cursor.getInt(mIsBinary_index) != 0) { viewHolder.binaryText.setVisibility(View.VISIBLE); // If it is binary and not an image we don't need to tag diff-related data if (cursor.getInt(mIsImage_index) == 0) { return convertView; } } else { viewHolder.binaryText.setVisibility(View.GONE); } // We have already set an anonymous tag so we need to use ids convertView.setTag(R.id.changeNumber, cursor.getInt(mCommit_index)); convertView.setTag(R.id.filePath, cursor.getString(mFileName_index)); convertView.setTag(R.id.patchSetNumber, cursor.getInt(mPatchSet_index)); convertView.setEnabled(true); return convertView; } // launches internal diff viewer public static void launchDiffViewer(Context context, Integer changeNumber, Integer patchSetNumber, String filePath) { Intent diffIntent = new Intent(context, DiffViewer.class); diffIntent.putExtra(DiffViewer.CHANGE_NUMBER_TAG, changeNumber); diffIntent.putExtra(DiffViewer.PATCH_SET_NUMBER_TAG, patchSetNumber); diffIntent.putExtra(DiffViewer.FILE_PATH_TAG, filePath); context.startActivity(diffIntent); } public static void launchDiffInBrowser(Context context, Integer changeNumber, Integer patchset, String filePath) { String base = "%s#/c/%d/%d/%s,unified"; Intent browserIntent = new Intent( Intent.ACTION_VIEW, Uri.parse(String.format(base, Prefs.getCurrentGerrit(context), changeNumber, patchset, filePath))); context.startActivity(browserIntent); } public static void launchDiffOptionDialog(final Context context, final Integer changeNumber, final Integer patchset, final String filePath) { View checkBoxView = View.inflate(context, R.layout.diff_option_checkbox, null); final CheckBox checkBox = (CheckBox) checkBoxView.findViewById(R.id.checkbox); AlertDialog.Builder ad = new AlertDialog.Builder(context) .setTitle(R.string.choose_diff_view) .setView(checkBoxView) .setPositiveButton(R.string.context_menu_view_diff_viewer, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { if (checkBox.isChecked()) { Prefs.setDiffDefault(context, Prefs.DiffModes.INTERNAL); } launchDiffViewer(context, changeNumber, patchset, filePath); } }) .setNegativeButton( R.string.context_menu_diff_view_in_browser, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { if (checkBox.isChecked()) { Prefs.setDiffDefault(context, Prefs.DiffModes.EXTERNAL); } launchDiffInBrowser(context, changeNumber, patchset, filePath); } }); ad.create().show(); } public static boolean onViewClicked(Context context, View view) { if (view == null) return false; final Integer changeNumber = (Integer) view.getTag(R.id.changeNumber); final String filePath = (String) view.getTag(R.id.filePath); final Integer patchset = (Integer) view.getTag(R.id.patchSetNumber); if (changeNumber == null) return false; // If the server does not support diffs then do not show the dialog if (!Config.isDiffSupported(context)) { PatchSetChangesCard.launchDiffInBrowser(context, changeNumber, patchset, filePath); return true; } Prefs.DiffModes mode = Prefs.getDiffDefault(context); if (mode == Prefs.DiffModes.INTERNAL) { PatchSetChangesCard.launchDiffViewer(context, changeNumber, patchset, filePath); } else if (mode == Prefs.DiffModes.EXTERNAL) { PatchSetChangesCard.launchDiffInBrowser(context, changeNumber, patchset, filePath); } else { PatchSetChangesCard.launchDiffOptionDialog(context, changeNumber, patchset, filePath); } return true; } private void setupCusorIndicies(Cursor cursor) { if (cursor.getPosition() < 0) { cursor.moveToFirst(); } if (mChangeId_index == null) { mChangeId_index = cursor.getColumnIndex(FileChanges.C_CHANGE_ID); } if (mFileName_index == null) { mFileName_index = cursor.getColumnIndex(FileChanges.C_FILE_NAME); } if (mStatus_index == null) { mStatus_index = cursor.getColumnIndex(FileChanges.C_STATUS); } if (mIsBinary_index == null) { mIsBinary_index = cursor.getColumnIndex(FileChanges.C_ISBINARY); } if (mOldPath_index == null) { mOldPath_index = cursor.getColumnIndex(FileChanges.C_OLDPATH); } if (mInserted_index == null) { mInserted_index = cursor.getColumnIndex(FileChanges.C_LINES_INSERTED); } if (mDeleted_index == null) { mDeleted_index = cursor.getColumnIndex(FileChanges.C_LINES_DELETED); } if (mPatchSet_index == null) { mPatchSet_index = cursor.getColumnIndex(FileChanges.C_PATCH_SET_NUMBER); } if (mCommit_index == null) { mCommit_index = cursor.getColumnIndex(FileChanges.C_COMMIT_NUMBER); } if (mIsImage_index == null) { mIsImage_index = cursor.getColumnIndex(FileChanges.C_ISIMAGE); } } class ViewHolder { final TextView path; final TextView inserted; final TextView deleted; final View binaryText; final View insText; final View delText; final TextView oldPath; final View oldPathContainer; ViewHolder(View view) { path = (TextView)view.findViewById(R.id.changed_file_path); inserted = (TextView)view.findViewById(R.id.changed_file_inserted); deleted = (TextView)view.findViewById(R.id.changed_file_deleted); binaryText = view.findViewById(R.id.binary_text); insText = view.findViewById(R.id.inserted_text); delText = view.findViewById(R.id.deleted_text); oldPath = (TextView) view.findViewById(R.id.changed_file_old_path); oldPathContainer = view.findViewById(R.id.old_path_container); } } }