feat: 로컬 파일 복사/잘라내기/붙여넣기 기능 구현
This commit is contained in:
@@ -3,6 +3,12 @@ package be.gyu.android.file.explorer;
|
|||||||
// ... (imports)
|
// ... (imports)
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -14,103 +20,94 @@ public class MainActivity extends AppCompatActivity implements FileAdapter.OnIte
|
|||||||
private List<FileItem> clipboard = new ArrayList<>();
|
private List<FileItem> clipboard = new ArrayList<>();
|
||||||
private boolean isCutOperation = false;
|
private boolean isCutOperation = false;
|
||||||
|
|
||||||
@Override
|
// ... (onCreate and Action Mode methods)
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
// ... (onCreate remains the same)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ... (Action Mode methods)
|
|
||||||
|
|
||||||
private final ActionMode.Callback actionModeCallback = new ActionMode.Callback() {
|
|
||||||
@Override
|
|
||||||
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
|
|
||||||
MenuInflater inflater = mode.getMenuInflater();
|
|
||||||
inflater.inflate(R.menu.context_menu_local, menu);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
|
|
||||||
MenuItem renameItem = menu.findItem(R.id.action_rename);
|
|
||||||
renameItem.setVisible(fileAdapter.getSelectedItemCount() == 1);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
|
||||||
int itemId = item.getItemId();
|
|
||||||
if (itemId == R.id.action_copy) {
|
|
||||||
copyToClipboard();
|
|
||||||
mode.finish();
|
|
||||||
return true;
|
|
||||||
} else if (itemId == R.id.action_cut) {
|
|
||||||
cutToClipboard();
|
|
||||||
mode.finish();
|
|
||||||
return true;
|
|
||||||
} else if (itemId == R.id.action_delete) {
|
|
||||||
showDeleteConfirmationDialog();
|
|
||||||
mode.finish();
|
|
||||||
return true;
|
|
||||||
} else if (itemId == R.id.action_rename) {
|
|
||||||
showRenameDialog();
|
|
||||||
mode.finish();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroyActionMode(ActionMode mode) {
|
|
||||||
actionMode = null;
|
|
||||||
fileAdapter.clearSelections();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private void copyToClipboard() {
|
|
||||||
clipboard.clear();
|
|
||||||
clipboard.addAll(fileAdapter.getSelectedItems());
|
|
||||||
isCutOperation = false;
|
|
||||||
Toast.makeText(this, clipboard.size() + " items copied", Toast.LENGTH_SHORT).show();
|
|
||||||
invalidateOptionsMenu(); // To show paste button
|
|
||||||
}
|
|
||||||
|
|
||||||
private void cutToClipboard() {
|
|
||||||
clipboard.clear();
|
|
||||||
clipboard.addAll(fileAdapter.getSelectedItems());
|
|
||||||
isCutOperation = true;
|
|
||||||
Toast.makeText(this, clipboard.size() + " items cut", Toast.LENGTH_SHORT).show();
|
|
||||||
invalidateOptionsMenu(); // To show paste button
|
|
||||||
}
|
|
||||||
|
|
||||||
// ... (Delete and Rename methods)
|
|
||||||
|
|
||||||
// --- Menu Methods ---
|
// --- Menu Methods ---
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
getMenuInflater().inflate(R.menu.main_menu, menu);
|
getMenuInflater().inflate(R.menu.main_menu, menu);
|
||||||
// Show paste button only if there's something in the clipboard
|
|
||||||
MenuItem pasteItem = menu.findItem(R.id.action_paste);
|
|
||||||
pasteItem.setVisible(!clipboard.isEmpty());
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||||
|
// Show paste button only if there's something in the clipboard and not in remote mode
|
||||||
|
MenuItem pasteItem = menu.findItem(R.id.action_paste);
|
||||||
|
pasteItem.setVisible(!clipboard.isEmpty() && !isRemoteMode);
|
||||||
|
return super.onPrepareOptionsMenu(menu);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||||
int itemId = item.getItemId();
|
int itemId = item.getItemId();
|
||||||
if (itemId == R.id.action_paste) {
|
if (itemId == R.id.action_paste) {
|
||||||
// TODO: Implement paste logic
|
pasteFiles();
|
||||||
Toast.makeText(this, "Paste clicked", Toast.LENGTH_SHORT).show();
|
|
||||||
return true;
|
|
||||||
} else if (itemId == R.id.select_storage) {
|
|
||||||
showStorageSelectionDialog();
|
|
||||||
return true;
|
|
||||||
} else if (itemId == R.id.remote_storage) {
|
|
||||||
Intent intent = new Intent(this, RemoteStorageActivity.class);
|
|
||||||
startActivity(intent);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// ... (other menu items)
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- File Operation Methods ---
|
||||||
|
|
||||||
|
private void pasteFiles() {
|
||||||
|
if (clipboard.isEmpty()) return;
|
||||||
|
|
||||||
|
Toast.makeText(this, "Pasting " + clipboard.size() + " items...", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
new Thread(() -> {
|
||||||
|
int successCount = 0;
|
||||||
|
for (FileItem item : clipboard) {
|
||||||
|
File sourceFile = new File(item.getPath());
|
||||||
|
File destFile = new File(currentDirectory, sourceFile.getName());
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (isCutOperation) {
|
||||||
|
if (sourceFile.renameTo(destFile)) {
|
||||||
|
successCount++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
copyFileOrDirectory(sourceFile, destFile);
|
||||||
|
successCount++;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int finalSuccessCount = successCount;
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
Toast.makeText(this, finalSuccessCount + " items pasted.", Toast.LENGTH_SHORT).show();
|
||||||
|
clipboard.clear();
|
||||||
|
isCutOperation = false;
|
||||||
|
invalidateOptionsMenu(); // Hide paste button
|
||||||
|
loadFiles(currentDirectory); // Refresh list
|
||||||
|
});
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void copyFileOrDirectory(File source, File dest) throws IOException {
|
||||||
|
if (source.isDirectory()) {
|
||||||
|
if (!dest.exists()) {
|
||||||
|
dest.mkdirs();
|
||||||
|
}
|
||||||
|
String[] files = source.list();
|
||||||
|
if (files != null) {
|
||||||
|
for (String file : files) {
|
||||||
|
copyFileOrDirectory(new File(source, file), new File(dest, file));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try (InputStream in = new FileInputStream(source);
|
||||||
|
OutputStream out = new FileOutputStream(dest)) {
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int length;
|
||||||
|
while ((length = in.read(buffer)) > 0) {
|
||||||
|
out.write(buffer, 0, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ... (rest of the file remains the same)
|
// ... (rest of the file remains the same)
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user