diff --git a/Aria/src/main/java/com/arialyy/aria/core/command/group/AbsGroupCmd.java b/Aria/src/main/java/com/arialyy/aria/core/command/group/AbsGroupCmd.java index 9dca385f..e73abdbd 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/command/group/AbsGroupCmd.java +++ b/Aria/src/main/java/com/arialyy/aria/core/command/group/AbsGroupCmd.java @@ -19,6 +19,7 @@ import android.util.Log; import com.arialyy.aria.core.command.AbsCmd; import com.arialyy.aria.core.download.DownloadGroupTaskEntity; import com.arialyy.aria.core.inf.AbsGroupTask; +import com.arialyy.aria.core.inf.AbsTask; import com.arialyy.aria.core.inf.BaseGroupTaskEntity; import com.arialyy.aria.core.queue.DownloadGroupTaskQueue; import com.arialyy.aria.util.CommonUtil; @@ -48,11 +49,24 @@ public abstract class AbsGroupCmd extends AbsCmd< } } + /** + * 创建任务 + * + * @return 创建的任务 + */ + AbsTask createTask() { + tempTask = (AbsGroupTask) mQueue.createTask(mTargetName, mTaskEntity); + return tempTask; + } + boolean checkTask() { tempTask = (AbsGroupTask) mQueue.getTask(mTaskEntity.getEntity()); - if (tempTask == null || !tempTask.isRunning()) { - Log.d(TAG, "任务组没有执行,先执行任务组任务才能够执行子任务"); - return false; + if (tempTask == null) { + createTask(); + if (tempTask.isComplete()) { + Log.w(TAG, "任务已完成"); + return false; + } } return true; } diff --git a/Aria/src/main/java/com/arialyy/aria/core/common/ProxyHelper.java b/Aria/src/main/java/com/arialyy/aria/core/common/ProxyHelper.java index c12ca3f2..d8da2277 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/common/ProxyHelper.java +++ b/Aria/src/main/java/com/arialyy/aria/core/common/ProxyHelper.java @@ -27,7 +27,7 @@ import static java.util.Collections.unmodifiableSet; * 代理参数获取 */ public class ProxyHelper { - public Set downloadCounter, uploadCounter, downloadGroupCounter; + public Set downloadCounter, uploadCounter, downloadGroupCounter, downloadGroupSubCounter; public static volatile ProxyHelper INSTANCE = null; @@ -49,6 +49,7 @@ public class ProxyHelper { Class clazz = Class.forName("com.arialyy.aria.ProxyClassCounter"); Method download = clazz.getMethod("getDownloadCounter"); Method downloadGroup = clazz.getMethod("getDownloadGroupCounter"); + Method downloadGroupSub = clazz.getMethod("getDownloadGroupSubCounter"); Method upload = clazz.getMethod("getUploadCounter"); Object object = clazz.newInstance(); Object dc = download.invoke(object); @@ -59,6 +60,10 @@ public class ProxyHelper { if (dgc != null) { downloadGroupCounter = unmodifiableSet((Set) dgc); } + Object dgsc = downloadGroupSub.invoke(object); + if (dgsc != null){ + downloadGroupSubCounter = unmodifiableSet((Set) dgsc); + } Object uc = upload.invoke(object); if (uc != null) { uploadCounter = unmodifiableSet((Set) uc); diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java index 735c3215..aeb323c3 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/DownloadReceiver.java @@ -139,10 +139,12 @@ public class DownloadReceiver extends AbsReceiver { String className = obj.getClass().getName(); Set dCounter = ProxyHelper.getInstance().downloadCounter; Set dgCounter = ProxyHelper.getInstance().downloadGroupCounter; + Set dgsCounter = ProxyHelper.getInstance().downloadGroupSubCounter; if (dCounter != null && dCounter.contains(className)) { DownloadSchedulers.getInstance().register(obj); } - if (dgCounter != null && dgCounter.contains(className)) { + if ((dgCounter != null && dgCounter.contains(className)) || (dgsCounter != null + && dgsCounter.contains(className))) { DownloadGroupSchedulers.getInstance().register(obj); } return this; @@ -155,10 +157,12 @@ public class DownloadReceiver extends AbsReceiver { String className = obj.getClass().getName(); Set dCounter = ProxyHelper.getInstance().downloadCounter; Set dgCounter = ProxyHelper.getInstance().downloadGroupCounter; + Set dgsCounter = ProxyHelper.getInstance().downloadGroupSubCounter; if (dCounter != null && dCounter.contains(className)) { DownloadSchedulers.getInstance().unRegister(obj); } - if (dgCounter != null && dgCounter.contains(className)) { + if (dgCounter != null && dgCounter.contains(className) || (dgsCounter != null + && dgsCounter.contains(className))) { DownloadGroupSchedulers.getInstance().unRegister(obj); } if (needRmReceiver) { diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/AbsGroupUtil.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/AbsGroupUtil.java index c5d9d164..65c353d4 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/AbsGroupUtil.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/AbsGroupUtil.java @@ -15,7 +15,6 @@ */ package com.arialyy.aria.core.download.downloader; -import android.util.Log; import com.arialyy.aria.core.AriaManager; import com.arialyy.aria.core.common.IUtil; import com.arialyy.aria.core.download.DownloadEntity; @@ -82,6 +81,8 @@ public abstract class AbsGroupUtil implements IUtil { private int mCompleteNum = 0; //失败的任务数 private int mFailNum = 0; + //停止的任务数 + private int mStopNum = 0; //实际的下载任务数 int mActualTaskNum = 0; /** @@ -98,6 +99,7 @@ public abstract class AbsGroupUtil implements IUtil { if (tasks != null && !tasks.isEmpty()) { for (DownloadTaskEntity te : tasks) { te.removeFile = mTaskEntity.removeFile; + if (te.getEntity() == null) continue; mTasksMap.put(te.getEntity().getUrl(), te); } } @@ -108,6 +110,7 @@ public abstract class AbsGroupUtil implements IUtil { if (entity.getState() == IEntity.STATE_COMPLETE && file.exists()) { mCompleteNum++; mInitNum++; + mStopNum++; mCurrentLocation += entity.getFileSize(); } else { mExeMap.put(entity.getUrl(), createChildDownloadTask(entity)); @@ -134,6 +137,10 @@ public abstract class AbsGroupUtil implements IUtil { * @param url 子任务下载地址 */ public void startSubTask(String url) { + isRunning = true; + if (mTimer == null) { + startTimer(); + } Downloader d = getDownloader(url); if (d != null && !d.isRunning()) { d.start(); @@ -172,8 +179,7 @@ public abstract class AbsGroupUtil implements IUtil { private Downloader getDownloader(String url) { Downloader d = mDownloaderMap.get(url); if (d == null) { - Log.e(TAG, "链接【" + url + "】对应的下载器不存在"); - return null; + return startChildDownload(mExeMap.get(url)); } return d; } @@ -283,6 +289,7 @@ public abstract class AbsGroupUtil implements IUtil { if (mTimer != null) { mTimer.purge(); mTimer.cancel(); + mTimer = null; } } @@ -293,6 +300,10 @@ public abstract class AbsGroupUtil implements IUtil { closeTimer(true); mListener.onPostPre(mTotalSize); mListener.onStart(mCurrentLocation); + startTimer(); + } + + private void startTimer() { mTimer = new Timer(true); mTimer.schedule(new TimerTask() { @Override public void run() { @@ -308,12 +319,13 @@ public abstract class AbsGroupUtil implements IUtil { /** * 启动子任务下载器 */ - void startChildDownload(DownloadTaskEntity taskEntity) { + Downloader startChildDownload(DownloadTaskEntity taskEntity) { ChildDownloadListener listener = new ChildDownloadListener(taskEntity); Downloader dt = new Downloader(listener, taskEntity); mDownloaderMap.put(taskEntity.getEntity().getUrl(), dt); - if (mExePool.isShutdown()) return; + if (mExePool.isShutdown()) return dt; mExePool.execute(dt); + return dt; } /** @@ -400,6 +412,11 @@ public abstract class AbsGroupUtil implements IUtil { saveData(IEntity.STATE_STOP, stopLocation); handleSpeed(0); mListener.onSubStop(entity); + mStopNum++; + if (mStopNum >= mInitNum) { + closeTimer(false); + mListener.onStop(mCurrentLocation); + } } @Override public void onCancel() { diff --git a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java index 296ff66e..5b3597c3 100644 --- a/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java +++ b/Aria/src/main/java/com/arialyy/aria/core/download/downloader/HttpThreadTask.java @@ -86,7 +86,6 @@ final class HttpThreadTask extends AbsThreadTask 0) Thread.sleep(mSleepTime); file.write(buffer, 0, len); progress(len); - Log.d(TAG, len + ""); } if (STATE.isCancel || STATE.isStop) return; //支持断点的处理 diff --git a/AriaAnnotations/src/main/java/com/arialyy/annotations/DownloadGroup.java b/AriaAnnotations/src/main/java/com/arialyy/annotations/DownloadGroup.java index 11521b9d..45cdd262 100644 --- a/AriaAnnotations/src/main/java/com/arialyy/annotations/DownloadGroup.java +++ b/AriaAnnotations/src/main/java/com/arialyy/annotations/DownloadGroup.java @@ -128,12 +128,12 @@ import java.lang.annotation.Target; String[] value() default { AriaConstance.NO_URL }; } - /** - * 任务组子任务删除的注解 - */ - @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onSubTaskCancel { - String[] value() default { AriaConstance.NO_URL }; - } + ///** + // * 任务组子任务删除的注解 + // */ + //@Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) @interface onSubTaskCancel { + // String[] value() default { AriaConstance.NO_URL }; + //} /** * 任务组子任务失败的注解 diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/AriaProcessor.java b/AriaCompiler/src/main/java/com/arialyy/compiler/AriaProcessor.java index 913bd72e..ede028cc 100644 --- a/AriaCompiler/src/main/java/com/arialyy/compiler/AriaProcessor.java +++ b/AriaCompiler/src/main/java/com/arialyy/compiler/AriaProcessor.java @@ -66,7 +66,7 @@ import javax.lang.model.element.TypeElement; annotataions.add(DownloadGroup.onTaskStop.class.getCanonicalName()); //任务组子任务的注解 annotataions.add(DownloadGroup.onSubTaskPre.class.getCanonicalName()); - annotataions.add(DownloadGroup.onSubTaskCancel.class.getCanonicalName()); + //annotataions.add(DownloadGroup.onSubTaskCancel.class.getCanonicalName()); annotataions.add(DownloadGroup.onSubTaskComplete.class.getCanonicalName()); annotataions.add(DownloadGroup.onSubTaskFail.class.getCanonicalName()); annotataions.add(DownloadGroup.onSubTaskRunning.class.getCanonicalName()); diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/CountFiler.java b/AriaCompiler/src/main/java/com/arialyy/compiler/CountFiler.java index d019aa09..ec874cd6 100644 --- a/AriaCompiler/src/main/java/com/arialyy/compiler/CountFiler.java +++ b/AriaCompiler/src/main/java/com/arialyy/compiler/CountFiler.java @@ -48,6 +48,7 @@ final class CountFiler { */ void createCountFile() throws IOException { Set keys = mPbUtil.getListenerClass().keySet(); + if (keys.size() == 0) return; TypeSpec.Builder builder = TypeSpec.classBuilder(ProxyConstance.PROXY_COUNTER_NAME) .addModifiers(Modifier.PUBLIC, Modifier.FINAL); @@ -76,6 +77,8 @@ final class CountFiler { createMethod(ProxyConstance.COUNT_METHOD_UPLOAD, ProxyConstance.COUNT_UPLOAD)); builder.addMethod(createMethod(ProxyConstance.COUNT_METHOD_DOWNLOAD_GROUP, ProxyConstance.COUNT_DOWNLOAD_GROUP)); + builder.addMethod(createMethod(ProxyConstance.COUNT_METHOD_DOWNLOAD_GROUP_SUB, + ProxyConstance.COUNT_DOWNLOAD_GROUP_SUB)); JavaFile jf = JavaFile.builder(ProxyConstance.PROXY_COUNTER_PACKAGE, builder.build()).build(); createFile(jf); @@ -113,6 +116,7 @@ final class CountFiler { } private void createFile(JavaFile jf) throws IOException { + //jf.writeTo(System.out); if (ProxyConstance.DEBUG) { // 如果需要在控制台打印生成的文件,则去掉下面的注释 jf.writeTo(System.out); diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/ElementHandler.java b/AriaCompiler/src/main/java/com/arialyy/compiler/ElementHandler.java index 50775981..bcb697a5 100644 --- a/AriaCompiler/src/main/java/com/arialyy/compiler/ElementHandler.java +++ b/AriaCompiler/src/main/java/com/arialyy/compiler/ElementHandler.java @@ -95,8 +95,8 @@ class ElementHandler { void handleDownloadGroupSub(RoundEnvironment roundEnv) { mPbUtil.saveMethod(TaskEnum.DOWNLOAD_GROUP_SUB, roundEnv, DownloadGroup.onSubTaskPre.class, ProxyConstance.TASK_PRE); - mPbUtil.saveMethod(TaskEnum.DOWNLOAD_GROUP_SUB, roundEnv, DownloadGroup.onSubTaskCancel.class, - ProxyConstance.TASK_CANCEL); + //mPbUtil.saveMethod(TaskEnum.DOWNLOAD_GROUP_SUB, roundEnv, DownloadGroup.onSubTaskCancel.class, + // ProxyConstance.TASK_CANCEL); mPbUtil.saveMethod(TaskEnum.DOWNLOAD_GROUP_SUB, roundEnv, DownloadGroup.onSubTaskComplete.class, ProxyConstance.TASK_COMPLETE); mPbUtil.saveMethod(TaskEnum.DOWNLOAD_GROUP_SUB, roundEnv, DownloadGroup.onSubTaskFail.class, @@ -146,5 +146,6 @@ class ElementHandler { void clean() { mPbUtil.getMethodParams().clear(); + mPbUtil.getListenerClass().clear(); } } diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/EventProxyFiler.java b/AriaCompiler/src/main/java/com/arialyy/compiler/EventProxyFiler.java index 1e382fd9..440b4bcc 100644 --- a/AriaCompiler/src/main/java/com/arialyy/compiler/EventProxyFiler.java +++ b/AriaCompiler/src/main/java/com/arialyy/compiler/EventProxyFiler.java @@ -78,21 +78,11 @@ final class EventProxyFiler { * 创建任务事件代理文件 */ void createEventProxyFile() throws IOException { - Map map = mPbUtil.getMethodParams(); Set keys = mPbUtil.getMethodParams().keySet(); for (String key : keys) { - //if (key.equals( - // "com.arialyy.simple.download.SingleTaskActivity$$DownloadGroupListenerProxy")) { - // - // ProxyClassParam entity = mPbUtil.getMethodParams().get(key); - // JavaFile jf = JavaFile.builder(entity.packageName, createProxyClass(entity)).build(); - // createFile(jf); - //} - ProxyClassParam entity = mPbUtil.getMethodParams().get(key); JavaFile jf = JavaFile.builder(entity.packageName, createProxyClass(entity)).build(); createFile(jf); - } } @@ -149,9 +139,6 @@ final class EventProxyFiler { builder.addParameter(subTaskParam); } - - //PrintLog.getInstance().info(builder.build().toString()); - return builder.build(); } diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyConstance.java b/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyConstance.java index 623f95c0..002d0d89 100644 --- a/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyConstance.java +++ b/AriaCompiler/src/main/java/com/arialyy/compiler/ProxyConstance.java @@ -47,6 +47,7 @@ interface ProxyConstance { String COUNT_METHOD_DOWNLOAD = "getDownloadCounter"; String COUNT_METHOD_DOWNLOAD_GROUP = "getDownloadGroupCounter"; + String COUNT_METHOD_DOWNLOAD_GROUP_SUB = "getDownloadGroupSubCounter"; String COUNT_METHOD_UPLOAD = "getUploadCounter"; int PRE = 0X11; diff --git a/AriaCompiler/src/main/java/com/arialyy/compiler/ValuesUtil.java b/AriaCompiler/src/main/java/com/arialyy/compiler/ValuesUtil.java index 86d5231c..f9c23f1c 100644 --- a/AriaCompiler/src/main/java/com/arialyy/compiler/ValuesUtil.java +++ b/AriaCompiler/src/main/java/com/arialyy/compiler/ValuesUtil.java @@ -47,7 +47,7 @@ final class ValuesUtil { values = method.getAnnotation(DownloadGroup.onSubTaskComplete.class).value(); break; case ProxyConstance.TASK_CANCEL: - values = method.getAnnotation(DownloadGroup.onSubTaskCancel.class).value(); + //values = method.getAnnotation(DownloadGroup.onSubTaskCancel.class).value(); break; case ProxyConstance.TASK_FAIL: values = method.getAnnotation(DownloadGroup.onSubTaskFail.class).value(); diff --git a/app/src/main/java/com/arialyy/simple/download/group/ChildHandleDialog.java b/app/src/main/java/com/arialyy/simple/download/group/ChildHandleDialog.java index 34369f31..6de6feed 100644 --- a/app/src/main/java/com/arialyy/simple/download/group/ChildHandleDialog.java +++ b/app/src/main/java/com/arialyy/simple/download/group/ChildHandleDialog.java @@ -18,7 +18,6 @@ package com.arialyy.simple.download.group; import android.annotation.SuppressLint; import android.content.Context; import android.os.Bundle; -import android.util.Log; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; @@ -31,6 +30,7 @@ import com.arialyy.annotations.DownloadGroup; import com.arialyy.aria.core.Aria; import com.arialyy.aria.core.download.DownloadEntity; import com.arialyy.aria.core.download.DownloadGroupTask; +import com.arialyy.frame.util.show.L; import com.arialyy.simple.R; import com.arialyy.simple.base.BaseDialog; import com.arialyy.simple.databinding.DialogSubTaskHandlerBinding; @@ -47,13 +47,15 @@ import java.util.List; @Bind(R.id.pb) HorizontalProgressBarWithNumber mPb; private String mGroupName; private String mChildName; + private List mUrls; private DownloadEntity mChildEntity; - public ChildHandleDialog(Context context, String groupAliaName, DownloadEntity childEntity) { + public ChildHandleDialog(Context context, List urls, DownloadEntity childEntity) { super(context); setStyle(STYLE_NO_TITLE, R.style.Theme_Light_Dialog); mChildEntity = childEntity; - mGroupName = groupAliaName; + mGroupName = "任务组测试"; + mUrls = urls; mChildName = childEntity.getFileName(); } @@ -81,39 +83,64 @@ import java.util.List; window.setWindowAnimations(R.style.dialogStyle); } - @DownloadGroup.onTaskResume void onTaskResume(DownloadGroupTask task) { - mSub.setText("子任务:" + mChildName + ",状态:下载中"); + @DownloadGroup.onSubTaskRunning void onSubTaskRunning(DownloadGroupTask groupTask, + DownloadEntity subEntity) { + if (!subEntity.getUrl().equals(mChildEntity.getUrl())) return; + L.d(TAG, "p ==> " + subEntity.getPercent()); + mPb.setProgress(subEntity.getPercent()); } - @DownloadGroup.onTaskCancel void onTaskCancel(DownloadGroupTask task) { - mSub.setText("子任务:" + mChildName + ",状态:取消下载"); + @DownloadGroup.onSubTaskPre void onSubTaskPre(DownloadGroupTask groupTask, + DownloadEntity subEntity) { + if (!subEntity.getUrl().equals(mChildEntity.getUrl())) return; + L.d(TAG, subEntity.getPercent() + ""); } - @DownloadGroup.onTaskRunning void onTaskRunning(DownloadGroupTask task) { - mPb.setProgress((int) (mChildEntity.getCurrentProgress() * 100 / mChildEntity.getFileSize())); - } - - @DownloadGroup.onTaskStop void onTaskStop(DownloadGroupTask task) { + @DownloadGroup.onSubTaskStop void onSubTaskStop(DownloadGroupTask groupTask, + DownloadEntity subEntity) { + if (!subEntity.getUrl().equals(mChildEntity.getUrl())) return; mSub.setText("子任务:" + mChildName + ",状态:任务停止"); } - @DownloadGroup.onTaskComplete void onTaskComplete(DownloadGroupTask task) { + @DownloadGroup.onSubTaskStart void onSubTaskStart(DownloadGroupTask groupTask, + DownloadEntity subEntity) { + if (!subEntity.getUrl().equals(mChildEntity.getUrl())) return; + mSub.setText("子任务:" + mChildName + ",状态:下载中"); + } + + //@DownloadGroup.onSubTaskCancel void onSubTaskCancel(DownloadGroupTask groupTask, + // DownloadEntity subEntity) { + // mSub.setText("子任务:" + mChildName + ",状态:取消下载"); + //} + + @DownloadGroup.onSubTaskComplete void onSubTaskComplete(DownloadGroupTask groupTask, + DownloadEntity subEntity) { + if (!subEntity.getUrl().equals(mChildEntity.getUrl())) return; mSub.setText("子任务:" + mChildName + ",状态:任务完成"); mPb.setProgress(100); } + @DownloadGroup.onSubTaskFail void onSubTaskFail(DownloadGroupTask groupTask, + DownloadEntity subEntity) { + if (!subEntity.getUrl().equals(mChildEntity.getUrl())) return; + L.d(TAG, subEntity.getPercent() + ""); + } + @Override protected int setLayoutId() { return R.layout.dialog_sub_task_handler; } - @OnClick({ R.id.start, R.id.stop, R.id.cancel }) void onClick(View view) { + @OnClick({ R.id.start, R.id.stop }) void onClick(View view) { switch (view.getId()) { case R.id.start: + Aria.download(this).load(mUrls).getSubTaskManager().startSubTask(mChildEntity.getUrl()); break; case R.id.stop: + Aria.download(this).load(mUrls).getSubTaskManager().stopSubTask(mChildEntity.getUrl()); break; - case R.id.cancel: - break; + //case R.id.cancel: + // Aria.download(this).load(mUrls).getSubTaskManager().cancelSubTask(mChildEntity.getUrl()); + // break; } } diff --git a/app/src/main/java/com/arialyy/simple/download/group/DownloadGroupActivity.java b/app/src/main/java/com/arialyy/simple/download/group/DownloadGroupActivity.java index 9ee5b60e..66b9034b 100644 --- a/app/src/main/java/com/arialyy/simple/download/group/DownloadGroupActivity.java +++ b/app/src/main/java/com/arialyy/simple/download/group/DownloadGroupActivity.java @@ -17,6 +17,7 @@ package com.arialyy.simple.download.group; import android.os.Bundle; import android.os.Environment; +import android.support.design.widget.FloatingActionButton; import android.view.View; import butterknife.Bind; import com.arialyy.annotations.DownloadGroup; @@ -64,11 +65,12 @@ public class DownloadGroupActivity extends BaseActivity - + + diff --git a/app/src/main/res/layout/dialog_sub_task_handler.xml b/app/src/main/res/layout/dialog_sub_task_handler.xml index 44f01a62..d833226f 100644 --- a/app/src/main/res/layout/dialog_sub_task_handler.xml +++ b/app/src/main/res/layout/dialog_sub_task_handler.xml @@ -61,14 +61,14 @@ style="?buttonBarButtonStyle" /> -