Commit 3ee030c9 authored by Geoffrey Métais's avatar Geoffrey Métais

Custom file picker for subs selection

parent d5416171
......@@ -76,13 +76,12 @@
android:name=".gui.SecondaryActivity"
android:windowSoftInputMode="adjustPan"
android:theme="@style/Theme.VLC"/>
<activity
android:name=".gui.browser.FilePickerActivity"
android:theme="@style/Theme.VLC.PickerDialog"/>
<activity android:name=".gui.CompatErrorActivity" />
<activity android:name=".gui.PreferencesActivity"
android:theme="@style/Theme.VLC" />
<activity
android:name=".gui.BrowserActivity"
android:label="@string/mediafiles"
android:theme="@style/Theme.VLC" />
<activity android:name=".gui.DebugLogActivity"
android:launchMode="singleTop" />
......
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="800dp"
android:layout_height="800dp">
<FrameLayout
android:id="@+id/fragment_placeholder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="@dimen/file_picker"
android:minHeight="@dimen/file_picker"/>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<org.videolan.vlc.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/swipeLayout"
android:layout_width="800dp"
android:layout_height="800dp">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.videolan.vlc.widget.ContextMenuRecyclerView
android:id="@+id/network_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"/>
<TextView
android:id="@+id/android:empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/network_connection_needed"/>
</FrameLayout>
</org.videolan.vlc.widget.SwipeRefreshLayout>
\ No newline at end of file
......@@ -29,6 +29,8 @@
<dimen name="tv_overscan_vertical">0dp</dimen>
<dimen name="tv_overscan_horizontal">0dp</dimen>
<dimen name="file_picker">600dip</dimen>
<!-- Default -->
<dimen name="default_margin">16dp</dimen>
<dimen name="half_default_margin">8dp</dimen>
......
......@@ -349,6 +349,7 @@
<string name="back_quit_lock">Press back again to quit video</string>
<string name="playlist_deleted">Playlist deleted</string>
<string name="file_deleted">File deleted</string>
<string name="no_subs_found">No subtitles in this directory</string>
<string-array name="hardware_acceleration_list">
<item>@string/automatic</item>
......
......@@ -78,6 +78,17 @@
<item name="ic_equalizer_normal_style">@drawable/ic_equalizer_normal</item>
</style>
<style name="Theme.VLC.PickerDialog" parent="Theme.AppCompat.Light.Dialog">
<item name="android:gridViewStyle">@style/Theme.VLC.List</item>
<item name="background_default">@color/grey50</item>
<item name="background_default_darker">@color/grey100</item>
<item name="font_default">@color/grey900</item>
<item name="font_light">@color/grey600</item>
<item name="list_subtitle">@color/list_subtitle</item>
<item name="list_title">@color/list_title</item>
<item name="android:windowBackground">@color/grey200</item>
</style>
<style name="Theme.VLC.Black" parent="Theme.VLC.Black.7"/>
<style name="Theme.VLC.Black.7" parent="Theme.VLC.Apearance.Black">
<item name="actionBarStyle">@style/ActionBar</item>
......
......@@ -117,7 +117,7 @@ public class BaseBrowserAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
public void onClick(View v) {
MediaWrapper mw = (MediaWrapper) getItem(holder.getAdapterPosition());
if (mw.getType() == MediaWrapper.TYPE_DIR)
fragment.browse(mw, holder.getAdapterPosition());
fragment.browse(mw, holder.getAdapterPosition(), true);
else if (mw.getType() == MediaWrapper.TYPE_VIDEO)
Util.openMedia(v.getContext(), mw);
else if (mw.getType() == MediaWrapper.TYPE_AUDIO) {
......@@ -321,7 +321,7 @@ public class BaseBrowserAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
notifyDataSetChanged();
}
private int getIconResId(MediaWrapper media) {
protected int getIconResId(MediaWrapper media) {
switch (media.getType()){
case MediaWrapper.TYPE_AUDIO:
return R.drawable.ic_browser_audio_normal;
......
......@@ -29,7 +29,6 @@ import android.os.Build;
import android.os.Bundle;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
......@@ -49,16 +48,14 @@ import android.widget.TextView;
import org.videolan.libvlc.Media;
import org.videolan.libvlc.util.AndroidUtil;
import org.videolan.libvlc.util.MediaBrowser;
import org.videolan.vlc.MediaLibrary;
import org.videolan.vlc.MediaWrapper;
import org.videolan.vlc.PlaybackServiceClient;
import org.videolan.vlc.R;
import org.videolan.vlc.VLCApplication;
import org.videolan.vlc.gui.SecondaryActivity;
import org.videolan.vlc.gui.dialogs.CommonDialogs;
import org.videolan.vlc.gui.DividerItemDecoration;
import org.videolan.vlc.gui.MainActivity;
import org.videolan.vlc.gui.SidebarAdapter;
import org.videolan.vlc.gui.SecondaryActivity;
import org.videolan.vlc.gui.dialogs.CommonDialogs;
import org.videolan.vlc.gui.video.VideoPlayerActivity;
import org.videolan.vlc.interfaces.IRefreshable;
import org.videolan.vlc.util.Util;
......@@ -119,15 +116,22 @@ public abstract class BaseBrowserFragment extends MediaBrowserFragment implement
else
mMrl = bundle.getString(KEY_MRL);
mSavedPosition = bundle.getInt(KEY_POSITION);
} else if (getActivity().getIntent() != null){
mMrl = getActivity().getIntent().getDataString();
getActivity().setIntent(null);
}
}
protected int getLayoutId(){
return R.layout.directory_browser;
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.directory_browser, container, false);
View v = inflater.inflate(getLayoutId(), container, false);
mRecyclerView = (ContextMenuRecyclerView) v.findViewById(R.id.network_list);
mEmptyView = (TextView) v.findViewById(android.R.id.empty);
mLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));
mRecyclerView.addItemDecoration(new DividerItemDecoration(VLCApplication.getAppContext(), DividerItemDecoration.VERTICAL_LIST));
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.addOnScrollListener(mScrollListener);
......@@ -195,7 +199,7 @@ public abstract class BaseBrowserFragment extends MediaBrowserFragment implement
getActivity().finish();
}
public void browse (MediaWrapper media, int position){
public void browse (MediaWrapper media, int position, boolean save){
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
Fragment next = createFragment();
Bundle args = new Bundle();
......@@ -205,7 +209,8 @@ public abstract class BaseBrowserFragment extends MediaBrowserFragment implement
args.putParcelable(KEY_MEDIA, media);
next.setArguments(args);
ft.replace(R.id.fragment_placeholder, next, media.getLocation());
ft.addToBackStack(mMrl);
if (save)
ft.addToBackStack(mMrl);
ft.commit();
}
......@@ -256,7 +261,6 @@ public abstract class BaseBrowserFragment extends MediaBrowserFragment implement
*/
protected void updateEmptyView(){
if (mAdapter.isEmpty()){
mEmptyView.setText(getString(R.string.directory_empty));
mEmptyView.setVisibility(View.VISIBLE);
mRecyclerView.setVisibility(View.GONE);
mSwipeRefreshLayout.setEnabled(false);
......@@ -334,10 +338,10 @@ public abstract class BaseBrowserFragment extends MediaBrowserFragment implement
}
protected void focusHelper() {
if (getActivity() == null)
if (getActivity() == null || !(getActivity() instanceof MainActivity))
return;
boolean isEmpty = mAdapter.isEmpty();
MainActivity main = (MainActivity)getActivity();
MainActivity main = (MainActivity) getActivity();
main.setMenuFocusDown(isEmpty, R.id.network_list);
main.setSearchAsFocusDown(isEmpty, getView(), R.id.network_list);
}
......
......@@ -24,31 +24,26 @@
package org.videolan.vlc.gui.browser;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.AppCompatEditText;
import android.text.InputType;
import android.text.TextUtils;
import android.view.MenuItem;
import android.view.View;
import org.videolan.libvlc.util.AndroidUtil;
import org.videolan.vlc.MediaDatabase;
import org.videolan.vlc.MediaLibrary;
import org.videolan.vlc.MediaWrapper;
import org.videolan.vlc.R;
import org.videolan.vlc.gui.AudioPlayerContainerActivity;
import org.videolan.vlc.util.AndroidDevices;
import org.videolan.vlc.util.CustomDirectories;
import org.videolan.vlc.util.Strings;
import org.videolan.vlc.util.Util;
import org.videolan.vlc.util.WeakHandler;
import java.io.File;
......@@ -67,6 +62,12 @@ public class FileBrowserFragment extends BaseBrowserFragment {
mRoot = mMrl == null;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mEmptyView.setText(getString(R.string.directory_empty));
}
@Override
protected Fragment createFragment() {
return new FileBrowserFragment();
......@@ -76,13 +77,14 @@ public class FileBrowserFragment extends BaseBrowserFragment {
if (mRoot)
return getCategoryTitle();
else {
String title = mMrl;
String title;
if (mCurrentMedia != null) {
if (TextUtils.equals(AndroidDevices.EXTERNAL_PUBLIC_DIRECTORY, mMrl))
if (TextUtils.equals(AndroidDevices.EXTERNAL_PUBLIC_DIRECTORY, Strings.removeFileProtocole(mMrl)))
title = getString(R.string.internal_memory);
else
title = mCurrentMedia.getTitle();
}
} else
title = Strings.getName(mMrl);
return title;
}
}
......@@ -110,7 +112,6 @@ public class FileBrowserFragment extends BaseBrowserFragment {
directory.setTitle(getString(R.string.internal_memory));
mAdapter.addItem(directory, false, false);
}
mHandler.sendEmptyMessage(BrowserFragmentHandler.MSG_HIDE_LOADING);
if (mReadyToDisplay) {
context.runOnUiThread(new Runnable() {
@Override
......
/*
* *************************************************************************
* FilePickerActivity.java
* **************************************************************************
* Copyright © 2015 VLC authors and VideoLAN
* Author: Geoffrey Métais
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
* ***************************************************************************
*/
package org.videolan.vlc.gui.browser;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import org.videolan.vlc.R;
public class FilePickerActivity extends AppCompatActivity {
protected static final String TAG = "VLC/BaseBrowserFragment";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.file_picker_activity);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragment_placeholder, new FilePickerFragment(), "picker");
ft.commit();
}
@Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
super.onBackPressed();
} else {
((FilePickerFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_placeholder)).browseUp();
}
}
}
/*
* *************************************************************************
* FilePickerAdapter.java
* **************************************************************************
* Copyright © 2015 VLC authors and VideoLAN
* Author: Geoffrey Métais
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
* ***************************************************************************
*/
package org.videolan.vlc.gui.browser;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.View;
import org.videolan.libvlc.Media;
import org.videolan.vlc.MediaWrapper;
public class FilePickerAdapter extends BaseBrowserAdapter {
public FilePickerAdapter(BaseBrowserFragment fragment) {
super(fragment);
}
public void addItem(Media media, boolean notify, boolean top){
MediaWrapper mediaWrapper = new MediaWrapper(media);
if (filter(mediaWrapper))
addItem(mediaWrapper, notify, top);
}
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
final MediaViewHolder vh = (MediaViewHolder) holder;
final MediaWrapper media = (MediaWrapper) getItem(position);
vh.checkBox.setVisibility(View.GONE);
vh.title.setText(media.getTitle());
if (!TextUtils.isEmpty(media.getDescription())) {
vh.text.setVisibility(View.VISIBLE);
vh.text.setText(media.getDescription());
} else
vh.text.setVisibility(View.INVISIBLE);
vh.icon.setImageResource(getIconResId(media));
vh.more.setVisibility(View.GONE);
vh.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (media.getType() == MediaWrapper.TYPE_DIR)
fragment.browse(media, holder.getAdapterPosition(), true);
else
((FilePickerFragment)fragment).pickFile(media);
}
});
}
//TODO update with different filter types in other cases than subtitles selection
private boolean filter(MediaWrapper mediaWrapper) {
return mediaWrapper.getType() == MediaWrapper.TYPE_DIR || mediaWrapper.getType() == MediaWrapper.TYPE_SUBTITLE;
}
}
/*
* *************************************************************************
* FilePickerFragment.java
* **************************************************************************
* Copyright © 2015 VLC authors and VideoLAN
* Author: Geoffrey Métais
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
* ***************************************************************************
*/
package org.videolan.vlc.gui.browser;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.view.View;
import org.videolan.vlc.MediaWrapper;
import org.videolan.vlc.R;
import org.videolan.vlc.util.Strings;
public class FilePickerFragment extends FileBrowserFragment {
@Override
protected Fragment createFragment() {
return new FilePickerFragment();
}
public FilePickerFragment(){}
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
mAdapter = new FilePickerAdapter(this);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mEmptyView.setText(R.string.no_subs_found);
}
@Override
public void onStart() {
super.onStart();
getActivity().setTitle(getTitle());
}
void pickFile(MediaWrapper mw){
getActivity().setResult(Activity.RESULT_OK, new Intent(Intent.ACTION_PICK, mw.getUri()));
getActivity().finish();
}
public void browseUp(){
if (mRoot)
getActivity().finish();
else if (TextUtils.equals(Strings.removeFileProtocole(mMrl), ROOT)) {
mMrl = null;
mRoot = true;
mAdapter.clear();
browseRoot();
} else {
MediaWrapper mw = new MediaWrapper(Uri.parse(Strings.getParent(mMrl)));
browse(mw, 0, false);
}
}
@Override
protected int getLayoutId(){
return R.layout.file_picker_fragment;
}
}
......@@ -45,7 +45,9 @@ public abstract class MediaBrowserFragment extends Fragment {
public abstract void clear();
public void onStart(){
super.onStart();
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle(getTitle());
getActivity().supportInvalidateOptionsMenu();
if (getActivity().getActionBar() != null) {
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle(getTitle());
getActivity().supportInvalidateOptionsMenu();
}
}
}
......@@ -106,6 +106,7 @@ import org.videolan.vlc.MediaWrapperListPlayer;
import org.videolan.vlc.PlaybackServiceClient;
import org.videolan.vlc.R;
import org.videolan.vlc.VLCApplication;
import org.videolan.vlc.gui.browser.FilePickerActivity;
import org.videolan.vlc.gui.dialogs.CommonDialogs;
import org.videolan.vlc.gui.MainActivity;
import org.videolan.vlc.gui.PreferencesActivity;
......@@ -1994,7 +1995,7 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
};
public void onAudioSubClick(View anchor){
final Context context = this;
final AppCompatActivity context = this;
PopupMenu popupMenu = new PopupMenu(this, anchor);
popupMenu.getMenuInflater().inflate(R.menu.audiosub_tracks, popupMenu.getMenu());
popupMenu.getMenu().findItem(R.id.video_menu_audio_track).setEnabled(MediaPlayer().getAudioTracksCount() > 2);
......@@ -2009,33 +2010,9 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
selectSubtitles();
return true;
} else if (item.getItemId() == R.id.video_menu_subtitles_picker) {
Intent intent = new Intent("org.openintents.action.PICK_FILE");
File file = new File(AndroidDevices.EXTERNAL_PUBLIC_DIRECTORY);
intent.setData(Uri.fromFile(file));
// Set fancy title and button (optional)
intent.putExtra("org.openintents.extra.TITLE", context.getString(R.string.subtitle_select));
intent.putExtra("org.openintents.extra.BUTTON_TEXT", context.getString(R.string.open));
if (getPackageManager()
.queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY).size() > 0) {
startActivityForResult(intent, CommonDialogs.INTENT_SPECIFIC);
} else {
// OI intent not found, trying anything
Intent intent2 = new Intent(Intent.ACTION_GET_CONTENT);
intent2.setType("*/*");
intent2.addCategory(Intent.CATEGORY_OPENABLE);
try {
startActivityForResult(intent2, CommonDialogs.INTENT_GENERIC);
} catch(ActivityNotFoundException e) {
Log.i(TAG, "No file picker found on system");
Toast.makeText(context,
R.string.no_file_picker_found,
Toast.LENGTH_SHORT).show();
}
}
Intent filePickerIntent = new Intent(context, FilePickerActivity.class);
filePickerIntent.setData(Uri.parse(Strings.getParent(MediaPlayer().getMedia().getUri().toString())));
context.startActivityForResult(filePickerIntent, 0);
return true;
}
return false;
......@@ -2047,6 +2024,7 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
private interface TrackSelectedListener {
public boolean onTrackSelected(int trackID);
}
private void selectTrack(final Map<Integer,String> trackMap, int currentTrack, int titleId,
final TrackSelectedListener listener) {
if (listener == null)
......
......@@ -156,6 +156,8 @@ public class Strings {
}
public static String removeFileProtocole(String path){
if (path == null)
return null;
if (path.startsWith("file://"))
return path.substring(7);
else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment