Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
handling disconnections & stability fixes
doesn't include ping/pong mechanism though
- Loading branch information
Showing
15 changed files
with
1,064 additions
and
896 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# warnings prevent build from continuing | ||
-ignorewarnings | ||
|
||
# if we do not use obfuscation, everything will fail | ||
# see http://stackoverflow.com/questions/5701126/compile-with-proguard-gives-exception-local-variable-type-mismatch | ||
#-dontobfuscate | ||
|
||
-dontskipnonpubliclibraryclasses | ||
-forceprocessing | ||
-optimizationpasses 5 | ||
|
||
# actionbarsherlock stuff | ||
-keep class android.support.v4.app.** { *; } | ||
-keep interface android.support.v4.app.** { *; } | ||
-keep class com.actionbarsherlock.** { *; } | ||
-keep interface com.actionbarsherlock.** { *; } | ||
-keepattributes *Annotation* | ||
|
||
# strip all logger calls | ||
# i hope the if (DEBUG) checks will get stripped too | ||
-assumenosideeffects class org.slf4j.Logger { | ||
public void error(...); | ||
public void warn(...); | ||
public void debug(...); | ||
public void trace(...); | ||
} |
272 changes: 162 additions & 110 deletions
272
weechat-android/src/main/java/com/ubergeek42/WeechatAndroid/MainPagerAdapter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,149 +1,201 @@ | ||
package com.ubergeek42.WeechatAndroid; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Iterator; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import android.os.Bundle; | ||
import android.os.Parcelable; | ||
import android.support.v4.app.Fragment; | ||
import android.support.v4.app.FragmentManager; | ||
import android.support.v4.app.FragmentStatePagerAdapter; | ||
import android.support.v4.app.FragmentTransaction; | ||
import android.support.v4.view.PagerAdapter; | ||
import android.support.v4.view.ViewPager; | ||
import android.view.View; | ||
import android.view.ViewGroup; | ||
|
||
import com.ubergeek42.WeechatAndroid.fragments.BufferFragment; | ||
import com.ubergeek42.WeechatAndroid.fragments.BufferListFragment; | ||
|
||
public class MainPagerAdapter extends FragmentStatePagerAdapter { | ||
private static Logger logger = LoggerFactory.getLogger(MainPagerAdapter.class); | ||
private BufferListFragment bufferListFragment = null; | ||
private ArrayList<BufferFragment> buffers = new ArrayList<BufferFragment>(); | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.util.ArrayList; | ||
|
||
public class MainPagerAdapter extends PagerAdapter { | ||
|
||
private static Logger logger = LoggerFactory.getLogger("MainPagerAdapter"); | ||
final private static boolean DEBUG = BuildConfig.DEBUG && true; | ||
|
||
private boolean phone_mode = false; | ||
private ArrayList<String> names = new ArrayList<String>(); | ||
private ArrayList<Fragment> fragments = new ArrayList<Fragment>(); | ||
private ViewPager pager; | ||
|
||
public MainPagerAdapter(FragmentManager fm) throws Exception { | ||
super(fm); | ||
throw new Exception("Should not ever be used!"); | ||
} | ||
|
||
public MainPagerAdapter(FragmentManager fm, ViewPager p) { | ||
super(fm); | ||
pager = p; | ||
} | ||
public void setBuffers(ArrayList<BufferFragment> frags) { | ||
buffers = frags; | ||
private FragmentManager manager; | ||
private FragmentTransaction transaction = null; | ||
|
||
|
||
public MainPagerAdapter(FragmentManager manager, ViewPager pager) { | ||
super(); | ||
this.manager = manager; | ||
this.pager = pager; | ||
} | ||
|
||
public void setBufferList(BufferListFragment blf) { | ||
bufferListFragment = blf; | ||
public void firstTimeInit(boolean phone_mode) { | ||
this.phone_mode = phone_mode; | ||
if (phone_mode) { | ||
names.add(""); | ||
fragments.add(new BufferListFragment()); | ||
} | ||
} | ||
|
||
/////////////////////// | ||
/////////////////////// | ||
/////////////////////// | ||
|
||
@Override | ||
public int getCount() { | ||
if (bufferListFragment==null) | ||
return buffers.size(); | ||
else | ||
return 1+buffers.size(); | ||
return names.size(); | ||
} | ||
|
||
/** this can be called either when a new fragment is being added or the old one is being | ||
** shown. in both cases the fragment will be in this.fragments, but in the latter case it | ||
** will not have been added to the fragment manager */ | ||
@Override | ||
public Fragment getItem(int pos) { | ||
// Tablet view | ||
if (bufferListFragment==null) | ||
return buffers.get(pos); | ||
|
||
// Not tablet view | ||
if (pos==0) { | ||
return bufferListFragment; | ||
public Object instantiateItem(ViewGroup container, int i) { | ||
if (DEBUG) logger.info("instantiateItem(..., {})", i); | ||
if (transaction == null) | ||
transaction = manager.beginTransaction(); | ||
Fragment f = manager.findFragmentByTag(names.get(i)); | ||
if (f != null) { | ||
if (DEBUG) logger.info("instantiateItem(): attach"); // show can be used instead | ||
transaction.attach(f); | ||
} else { | ||
return buffers.get(pos-1); | ||
f = fragments.get(i); | ||
if (DEBUG) logger.info("instantiateItem(): add"); | ||
transaction.add(container.getId(), f, names.get(i)); | ||
} | ||
return f; | ||
} | ||
|
||
/** this can be called either when a fragment has been removed by closeBuffer or when it's | ||
** getting off-screen. in the first case the fragment will still be in this.fragments */ | ||
@Override | ||
public CharSequence getPageTitle(int pos) { | ||
// Tablet view | ||
if (bufferListFragment==null) { | ||
String title = buffers.get(pos).getShortBufferName(); | ||
if (title==null || title.equals("")){ | ||
return buffers.get(pos).getBufferName(); | ||
} | ||
return title; | ||
} | ||
|
||
// Phone view | ||
if (pos==0) { | ||
return "Buffer List"; | ||
public void destroyItem(ViewGroup container, int i, Object object) { | ||
if (DEBUG) logger.info("destroyItem(..., {}, {})", i, object); | ||
if (transaction == null) | ||
transaction = manager.beginTransaction(); | ||
if (fragments.size() > i && fragments.get(i) == object) { | ||
if (DEBUG) logger.info("destroyItem(): detach"); // hide can be used instead | ||
transaction.detach((Fragment) object); | ||
} else { | ||
String title = buffers.get(pos-1).getShortBufferName(); | ||
if (title==null || title.equals("")){ | ||
return buffers.get(pos-1).getBufferName(); | ||
} | ||
return title; | ||
if (DEBUG) logger.info("destroyItem(): remove"); | ||
transaction.remove((Fragment) object); | ||
} | ||
} | ||
|
||
public void closeBuffer(String buffer) { | ||
int i=0; | ||
Iterator<BufferFragment> iter = buffers.iterator(); | ||
while(iter.hasNext()) { | ||
BufferFragment bf = iter.next(); | ||
if (bf.getBufferName().equals(buffer)) { | ||
// TODO: wrong thread error for pager.setCurrentItem | ||
pager.setCurrentItem(i); | ||
iter.remove(); | ||
} | ||
i++; | ||
} | ||
notifyDataSetChanged(); | ||
|
||
@Override | ||
public boolean isViewFromObject(View view, Object object) { | ||
return ((Fragment) object).getView() == view; | ||
} | ||
public void openBuffer(String buffer) { | ||
// Find the appropriate buffer in our list | ||
for (int i=0;i<buffers.size(); i++) { | ||
BufferFragment bf = buffers.get(i); | ||
if (bf.getBufferName().equals(buffer)) { | ||
|
||
if (bufferListFragment == null) { | ||
pager.setCurrentItem(i); | ||
} else { | ||
pager.setCurrentItem(i+1); | ||
} | ||
// TODO: update title? | ||
return; | ||
} | ||
} | ||
|
||
// Create fragment for the buffer and setup the arguments | ||
BufferFragment newFragment = new BufferFragment(); | ||
Bundle args = new Bundle(); | ||
args.putString("buffer", buffer); | ||
newFragment.setArguments(args); | ||
buffers.add(newFragment); | ||
notifyDataSetChanged(); | ||
pager.setCurrentItem(buffers.size()); | ||
|
||
/** this should return index for fragments or POSITION_NONE if a fragment has been removed | ||
** providing proper indexes instead of POSITION_NONE allows buffers not to be | ||
** fully recreated on every buffer list change */ | ||
@Override | ||
public int getItemPosition(Object object) { | ||
int idx = fragments.indexOf(object); | ||
if (DEBUG) logger.info("getItemPosition(...) -> {}", (idx >= 0) ? idx : POSITION_NONE); | ||
return (idx >= 0) ? idx : POSITION_NONE; | ||
} | ||
|
||
/** this one's empty because instantiateItem and destroyItem create transactions as needed | ||
** this function is called too frequently to create a transaction inside it*/ | ||
@Override | ||
public void startUpdate(ViewGroup container) {} | ||
|
||
/** this function, too, is called way too frequently */ | ||
@Override | ||
public void finishUpdate(ViewGroup container) { | ||
if (transaction == null) | ||
return; | ||
transaction.commitAllowingStateLoss(); | ||
transaction = null; | ||
manager.executePendingTransactions(); | ||
} | ||
|
||
@Override | ||
public CharSequence getPageTitle(int i) { | ||
return (phone_mode && i == 0) ? "Buffer List" : ((BufferFragment) fragments.get(i)).getShortBufferName(); | ||
} | ||
|
||
public BufferFragment getCurrentBuffer() { | ||
int pos = pager.getCurrentItem(); | ||
if (bufferListFragment == null) { | ||
// Tablet view | ||
if (pos>=0 && pos < buffers.size()) { | ||
return buffers.get(pos); | ||
} | ||
/** switch to already open buffer OR create a new buffer, putting it into BOTH names and fragments, | ||
** run notifyDataSetChanged() which will in turn call instantiateItem(), and set new buffer as the current one */ | ||
public void openBuffer(String name) { | ||
if (DEBUG) logger.info("openBuffer({})", name); | ||
int idx = names.indexOf(name); | ||
if (idx >= 0) { | ||
// found buffer by name, switch to it | ||
pager.setCurrentItem(idx); | ||
} else { | ||
// Phone view | ||
if (pos>=1 && pos <= buffers.size()) { | ||
return buffers.get(pos-1); | ||
} | ||
// create a new one | ||
Fragment f = new BufferFragment(); | ||
Bundle args = new Bundle(); | ||
args.putString("buffer", name); | ||
f.setArguments(args); | ||
fragments.add(f); | ||
names.add(name); | ||
notifyDataSetChanged(); | ||
pager.setCurrentItem(names.size()); | ||
} | ||
return null; | ||
} | ||
|
||
|
||
/** close buffer if open, removing it from BOTH names and fragments. | ||
** destroyItem() checks the lists to see if it has to remove the item for good */ | ||
public void closeBuffer(String name) { | ||
if (DEBUG) logger.info("closeBuffer({})", name); | ||
int idx = names.indexOf(name); | ||
if (idx >= 0) { | ||
names.remove(idx); | ||
fragments.remove(idx); | ||
notifyDataSetChanged(); | ||
} | ||
} | ||
|
||
/** returns BufferFragment that is currently focused | ||
** or null if nothing or BufferListFragment is focused */ | ||
public BufferFragment getCurrentBuffer() { | ||
int i = pager.getCurrentItem(); | ||
if ((phone_mode && i == 0) || fragments.size() == 0) | ||
return null; | ||
else | ||
return (BufferFragment) fragments.get(i); | ||
} | ||
|
||
/** the following two methods magically get called on application recreation, | ||
** so put all our save/restore state here */ | ||
@Override | ||
public int getItemPosition(Object object) { | ||
return POSITION_NONE; | ||
public Parcelable saveState() { | ||
if (DEBUG) logger.info("saveState()"); | ||
if (fragments.size() == 0) | ||
return null; | ||
Bundle state = new Bundle(); | ||
state.putStringArrayList("\0", names); | ||
for (int i = 0, size = names.size(); i < size; i++) | ||
manager.putFragment(state, names.get(i), fragments.get(i)); | ||
return state; | ||
} | ||
|
||
@Override | ||
public void restoreState(Parcelable parcel, ClassLoader loader) { | ||
if (DEBUG) logger.info("restoreState()"); | ||
if (parcel == null) | ||
return; | ||
Bundle state = (Bundle) parcel; | ||
state.setClassLoader(loader); | ||
names = state.getStringArrayList("\0"); | ||
if (names.size() > 0) { | ||
for (String name : names) | ||
fragments.add(manager.getFragment(state, name)); | ||
phone_mode = names.get(0).equals(""); | ||
notifyDataSetChanged(); | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.