Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
J
jadx
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open-source
jadx
Commits
bc73010d
Commit
bc73010d
authored
Jul 26, 2015
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gui: add find usage feature, run decompilation and index jobs in background (#74, #75)
parent
2d8d4164
Hide whitespace changes
Inline
Side-by-side
Showing
33 changed files
with
1520 additions
and
294 deletions
+1520
-294
NOTICE
NOTICE
+22
-2
FieldInitAttr.java
...c/main/java/jadx/core/dex/nodes/parser/FieldInitAttr.java
+1
-1
build.gradle
jadx-gui/build.gradle
+1
-1
BackgroundJob.java
jadx-gui/src/main/java/jadx/gui/jobs/BackgroundJob.java
+87
-0
BackgroundWorker.java
jadx-gui/src/main/java/jadx/gui/jobs/BackgroundWorker.java
+99
-0
DecompileJob.java
jadx-gui/src/main/java/jadx/gui/jobs/DecompileJob.java
+28
-0
IndexJob.java
jadx-gui/src/main/java/jadx/gui/jobs/IndexJob.java
+76
-0
JadxSettings.java
jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java
+14
-6
JadxSettingsAdapter.java
.../src/main/java/jadx/gui/settings/JadxSettingsAdapter.java
+4
-1
JadxSettingsWindow.java
...i/src/main/java/jadx/gui/settings/JadxSettingsWindow.java
+9
-0
CodeNode.java
jadx-gui/src/main/java/jadx/gui/treemodel/CodeNode.java
+41
-13
JClass.java
jadx-gui/src/main/java/jadx/gui/treemodel/JClass.java
+11
-0
JField.java
jadx-gui/src/main/java/jadx/gui/treemodel/JField.java
+16
-0
JMethod.java
jadx-gui/src/main/java/jadx/gui/treemodel/JMethod.java
+23
-3
JNode.java
jadx-gui/src/main/java/jadx/gui/treemodel/JNode.java
+25
-5
JPackage.java
jadx-gui/src/main/java/jadx/gui/treemodel/JPackage.java
+4
-1
JResource.java
jadx-gui/src/main/java/jadx/gui/treemodel/JResource.java
+1
-1
CommonSearchDialog.java
jadx-gui/src/main/java/jadx/gui/ui/CommonSearchDialog.java
+394
-0
ContentArea.java
jadx-gui/src/main/java/jadx/gui/ui/ContentArea.java
+84
-15
MainDropTarget.java
jadx-gui/src/main/java/jadx/gui/ui/MainDropTarget.java
+1
-5
MainWindow.java
jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
+58
-9
ProgressPanel.java
jadx-gui/src/main/java/jadx/gui/ui/ProgressPanel.java
+82
-0
SearchDialog.java
jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java
+32
-204
TabbedPane.java
jadx-gui/src/main/java/jadx/gui/ui/TabbedPane.java
+36
-2
UsageDialog.java
jadx-gui/src/main/java/jadx/gui/ui/UsageDialog.java
+101
-0
CacheObject.java
jadx-gui/src/main/java/jadx/gui/utils/CacheObject.java
+46
-2
CodeLinesInfo.java
jadx-gui/src/main/java/jadx/gui/utils/CodeLinesInfo.java
+36
-0
CodeUsageInfo.java
jadx-gui/src/main/java/jadx/gui/utils/CodeUsageInfo.java
+57
-0
LogCollector.java
jadx-gui/src/main/java/jadx/gui/utils/LogCollector.java
+1
-1
SuffixTree.java
jadx-gui/src/main/java/jadx/gui/utils/SuffixTree.java
+28
-0
TextSearchIndex.java
jadx-gui/src/main/java/jadx/gui/utils/TextSearchIndex.java
+72
-22
Utils.java
jadx-gui/src/main/java/jadx/gui/utils/Utils.java
+26
-0
Messages_en_US.properties
jadx-gui/src/main/resources/i18n/Messages_en_US.properties
+4
-0
No files found.
NOTICE
View file @
bc73010d
...
@@ -144,7 +144,8 @@ THE POSSIBILITY OF SUCH DAMAGE.
...
@@ -144,7 +144,8 @@ THE POSSIBILITY OF SUCH DAMAGE.
Jadx-gui components
Jadx-gui components
===================
===================
RSyntaxTextArea library licensed under modified BSD license:
RSyntaxTextArea library (https://github.com/bobbylight/RSyntaxTextArea)
licensed under modified BSD license:
*******************************************************************************
*******************************************************************************
Copyright (c) 2012, Robert Futrell
Copyright (c) 2012, Robert Futrell
...
@@ -174,8 +175,27 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
...
@@ -174,8 +175,27 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************
*******************************************************************************
Concurrent Trees (https://code.google.com/p/concurrent-trees/)
licenced under Apache License 2.0:
*******************************************************************************
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.
*******************************************************************************
Icons copied from several places:
Icons copied from several places:
- Eclipse Project (JDT UI) - licensed under EPL v1.0 (http://www.eclipse.org/legal/epl-v10.html)
- Eclipse Project (JDT UI) - licensed under EPL v1.0 (http://www.eclipse.org/legal/epl-v10.html)
- famfamfam silk icon set (http://www.famfamfam.com/lab/icons/silk/) - licensed under Creative Commons Attribution 2.5 License (http://creativecommons.org/licenses/by/2.5/)
- famfamfam silk icon set (http://www.famfamfam.com/lab/icons/silk/) - licensed
under Creative Commons Attribution 2.5 License (http://creativecommons.org/licenses/by/2.5/)
JFontChooser Component - http://sourceforge.jp/projects/jfontchooser/
JFontChooser Component - http://sourceforge.jp/projects/jfontchooser/
jadx-core/src/main/java/jadx/core/dex/nodes/parser/FieldInitAttr.java
View file @
bc73010d
...
@@ -7,7 +7,7 @@ import jadx.core.dex.nodes.MethodNode;
...
@@ -7,7 +7,7 @@ import jadx.core.dex.nodes.MethodNode;
public
class
FieldInitAttr
implements
IAttribute
{
public
class
FieldInitAttr
implements
IAttribute
{
public
static
FieldInitAttr
NULL_VALUE
=
constValue
(
null
);
public
static
final
FieldInitAttr
NULL_VALUE
=
constValue
(
null
);
public
enum
InitType
{
public
enum
InitType
{
CONST
,
CONST
,
...
...
jadx-gui/build.gradle
View file @
bc73010d
...
@@ -5,7 +5,7 @@ mainClassName = 'jadx.gui.JadxGUI'
...
@@ -5,7 +5,7 @@ mainClassName = 'jadx.gui.JadxGUI'
dependencies
{
dependencies
{
compile
(
project
(
":jadx-core"
))
compile
(
project
(
":jadx-core"
))
compile
(
project
(
":jadx-cli"
))
compile
(
project
(
":jadx-cli"
))
compile
'com.fifesoft:rsyntaxtextarea:2.5.
6
'
compile
'com.fifesoft:rsyntaxtextarea:2.5.
7
'
compile
'com.google.code.gson:gson:2.3.1'
compile
'com.google.code.gson:gson:2.3.1'
compile
files
(
'libs/jfontchooser-1.0.5.jar'
)
compile
files
(
'libs/jfontchooser-1.0.5.jar'
)
compile
'com.googlecode.concurrent-trees:concurrent-trees:2.4.0'
compile
'com.googlecode.concurrent-trees:concurrent-trees:2.4.0'
...
...
jadx-gui/src/main/java/jadx/gui/jobs/BackgroundJob.java
0 → 100644
View file @
bc73010d
package
jadx
.
gui
.
jobs
;
import
jadx.gui.JadxWrapper
;
import
java.util.concurrent.Callable
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.Future
;
import
java.util.concurrent.FutureTask
;
import
java.util.concurrent.ThreadPoolExecutor
;
import
java.util.concurrent.TimeUnit
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
public
abstract
class
BackgroundJob
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
DecompileJob
.
class
);
protected
final
JadxWrapper
wrapper
;
private
final
ThreadPoolExecutor
executor
;
private
Future
<
Boolean
>
future
;
public
BackgroundJob
(
JadxWrapper
wrapper
,
int
threadsCount
)
{
this
.
wrapper
=
wrapper
;
this
.
executor
=
(
ThreadPoolExecutor
)
Executors
.
newFixedThreadPool
(
threadsCount
);
}
public
synchronized
Future
<
Boolean
>
process
()
{
if
(
future
!=
null
)
{
return
future
;
}
ExecutorService
shutdownExecutor
=
Executors
.
newSingleThreadExecutor
();
FutureTask
<
Boolean
>
task
=
new
ShutdownTask
();
shutdownExecutor
.
execute
(
task
);
shutdownExecutor
.
shutdown
();
future
=
task
;
return
future
;
}
private
class
ShutdownTask
extends
FutureTask
<
Boolean
>
{
public
ShutdownTask
()
{
super
(
new
Callable
<
Boolean
>()
{
@Override
public
Boolean
call
()
throws
Exception
{
runJob
();
executor
.
shutdown
();
return
executor
.
awaitTermination
(
5
,
TimeUnit
.
MINUTES
);
}
});
}
@Override
public
boolean
cancel
(
boolean
mayInterruptIfRunning
)
{
executor
.
shutdownNow
();
return
super
.
cancel
(
mayInterruptIfRunning
);
}
}
protected
abstract
void
runJob
();
public
abstract
String
getInfoString
();
protected
void
addTask
(
Runnable
runnable
)
{
executor
.
execute
(
runnable
);
}
public
void
processAndWait
()
{
try
{
process
().
get
();
}
catch
(
Exception
e
)
{
LOG
.
error
(
"BackgroundJob.processAndWait failed"
,
e
);
}
}
public
synchronized
boolean
isComplete
()
{
try
{
return
future
!=
null
&&
future
.
isDone
();
}
catch
(
Exception
e
)
{
LOG
.
error
(
"BackgroundJob.isComplete failed"
,
e
);
return
false
;
}
}
public
int
getProgress
()
{
return
(
int
)
(
executor
.
getCompletedTaskCount
()
*
100
/
(
double
)
executor
.
getTaskCount
());
}
}
jadx-gui/src/main/java/jadx/gui/jobs/BackgroundWorker.java
0 → 100644
View file @
bc73010d
package
jadx
.
gui
.
jobs
;
import
jadx.gui.ui.ProgressPanel
;
import
jadx.gui.utils.CacheObject
;
import
jadx.gui.utils.TextSearchIndex
;
import
jadx.gui.utils.Utils
;
import
javax.swing.SwingUtilities
;
import
javax.swing.SwingWorker
;
import
java.util.concurrent.Future
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
public
class
BackgroundWorker
extends
SwingWorker
<
Void
,
Void
>
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
BackgroundWorker
.
class
);
private
final
CacheObject
cache
;
private
final
ProgressPanel
progressPane
;
public
BackgroundWorker
(
CacheObject
cacheObject
,
ProgressPanel
progressPane
)
{
this
.
cache
=
cacheObject
;
this
.
progressPane
=
progressPane
;
}
public
void
exec
()
{
if
(
isDone
())
{
return
;
}
SwingUtilities
.
invokeLater
(
new
Runnable
()
{
@Override
public
void
run
()
{
progressPane
.
setVisible
(
true
);
}
});
addPropertyChangeListener
(
progressPane
);
execute
();
}
public
void
stop
()
{
if
(
isDone
())
{
return
;
}
LOG
.
debug
(
"Canceling background jobs ..."
);
cancel
(
false
);
}
@Override
protected
Void
doInBackground
()
throws
Exception
{
try
{
System
.
gc
();
LOG
.
debug
(
"Memory usage: Before decompile: {}"
,
Utils
.
memoryInfo
());
runJob
(
cache
.
getDecompileJob
());
LOG
.
debug
(
"Memory usage: Before index: {}"
,
Utils
.
memoryInfo
());
runJob
(
cache
.
getIndexJob
());
LOG
.
debug
(
"Memory usage: After index: {}"
,
Utils
.
memoryInfo
());
System
.
gc
();
LOG
.
debug
(
"Memory usage: After gc: {}"
,
Utils
.
memoryInfo
());
TextSearchIndex
searchIndex
=
cache
.
getTextIndex
();
if
(
cache
.
getIndexJob
().
isUseFastSearch
()
&&
searchIndex
!=
null
&&
searchIndex
.
getSkippedCount
()
>
0
)
{
LOG
.
warn
(
"Indexing of some classes skipped, count: {}, low memory: {}"
,
searchIndex
.
getSkippedCount
(),
Utils
.
memoryInfo
());
}
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Exception in background worker"
,
e
);
}
return
null
;
}
private
void
runJob
(
BackgroundJob
job
)
{
if
(
isCancelled
())
{
return
;
}
progressPane
.
changeLabel
(
this
,
job
.
getInfoString
());
Future
<
Boolean
>
future
=
job
.
process
();
while
(!
future
.
isDone
())
{
try
{
setProgress
(
job
.
getProgress
());
if
(
isCancelled
())
{
future
.
cancel
(
false
);
}
Thread
.
sleep
(
500
);
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Background worker error"
,
e
);
}
}
}
@Override
protected
void
done
()
{
progressPane
.
setVisible
(
false
);
}
}
jadx-gui/src/main/java/jadx/gui/jobs/DecompileJob.java
0 → 100644
View file @
bc73010d
package
jadx
.
gui
.
jobs
;
import
jadx.api.JavaClass
;
import
jadx.gui.JadxWrapper
;
public
class
DecompileJob
extends
BackgroundJob
{
public
DecompileJob
(
JadxWrapper
wrapper
,
int
threadsCount
)
{
super
(
wrapper
,
threadsCount
);
}
protected
void
runJob
()
{
for
(
final
JavaClass
cls
:
wrapper
.
getClasses
())
{
addTask
(
new
Runnable
()
{
@Override
public
void
run
()
{
cls
.
decompile
();
}
});
}
}
@Override
public
String
getInfoString
()
{
return
"Decompiling: "
;
}
}
jadx-gui/src/main/java/jadx/gui/jobs/IndexJob.java
0 → 100644
View file @
bc73010d
package
jadx
.
gui
.
jobs
;
import
jadx.api.JavaClass
;
import
jadx.core.codegen.CodeWriter
;
import
jadx.gui.JadxWrapper
;
import
jadx.gui.settings.JadxSettings
;
import
jadx.gui.utils.CacheObject
;
import
jadx.gui.utils.CodeLinesInfo
;
import
jadx.gui.utils.CodeUsageInfo
;
import
jadx.gui.utils.TextSearchIndex
;
import
jadx.gui.utils.Utils
;
import
org.jetbrains.annotations.NotNull
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
public
class
IndexJob
extends
BackgroundJob
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
IndexJob
.
class
);
private
final
CacheObject
cache
;
private
final
boolean
useFastSearch
;
public
IndexJob
(
JadxWrapper
wrapper
,
JadxSettings
settings
,
CacheObject
cache
)
{
super
(
wrapper
,
settings
.
getThreadsCount
());
this
.
useFastSearch
=
settings
.
isUseFastSearch
();
this
.
cache
=
cache
;
}
protected
void
runJob
()
{
final
TextSearchIndex
index
=
new
TextSearchIndex
();
final
CodeUsageInfo
usageInfo
=
new
CodeUsageInfo
();
cache
.
setTextIndex
(
index
);
cache
.
setUsageInfo
(
usageInfo
);
for
(
final
JavaClass
cls
:
wrapper
.
getClasses
())
{
addTask
(
new
Runnable
()
{
@Override
public
void
run
()
{
try
{
index
.
indexNames
(
cls
);
CodeLinesInfo
linesInfo
=
new
CodeLinesInfo
(
cls
);
String
[]
lines
=
splitIntoLines
(
cls
);
usageInfo
.
processClass
(
cls
,
linesInfo
,
lines
);
if
(
useFastSearch
&&
Utils
.
isFreeMemoryAvailable
())
{
index
.
indexCode
(
cls
,
linesInfo
,
lines
);
}
else
{
index
.
classCodeIndexSkipped
(
cls
);
}
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Index error in class: {}"
,
cls
.
getFullName
(),
e
);
}
}
});
}
}
@NotNull
protected
String
[]
splitIntoLines
(
JavaClass
cls
)
{
String
[]
lines
=
cls
.
getCode
().
split
(
CodeWriter
.
NL
);
int
count
=
lines
.
length
;
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
lines
[
i
]
=
lines
[
i
].
trim
();
}
return
lines
;
}
@Override
public
String
getInfoString
()
{
return
"Indexing: "
;
}
public
boolean
isUseFastSearch
()
{
return
useFastSearch
;
}
}
jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java
View file @
bc73010d
...
@@ -2,7 +2,6 @@ package jadx.gui.settings;
...
@@ -2,7 +2,6 @@ package jadx.gui.settings;
import
jadx.cli.JadxCLIArgs
;
import
jadx.cli.JadxCLIArgs
;
import
javax.swing.JLabel
;
import
java.awt.Font
;
import
java.awt.Font
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Arrays
;
...
@@ -10,12 +9,14 @@ import java.util.HashSet;
...
@@ -10,12 +9,14 @@ import java.util.HashSet;
import
java.util.List
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.Set
;
import
org.fife.ui.rsyntaxtextarea.RSyntaxTextArea
;
public
class
JadxSettings
extends
JadxCLIArgs
{
public
class
JadxSettings
extends
JadxCLIArgs
{
private
static
final
String
USER_HOME
=
System
.
getProperty
(
"user.home"
);
private
static
final
String
USER_HOME
=
System
.
getProperty
(
"user.home"
);
private
static
final
int
RECENT_FILES_COUNT
=
15
;
private
static
final
int
RECENT_FILES_COUNT
=
15
;
private
static
final
Font
DEFAULT_FONT
=
new
JLabel
().
getFont
();
private
static
final
Font
DEFAULT_FONT
=
new
RSyntaxTextArea
().
getFont
();
static
final
Set
<
String
>
SKIP_FIELDS
=
new
HashSet
<
String
>(
Arrays
.
asList
(
static
final
Set
<
String
>
SKIP_FIELDS
=
new
HashSet
<
String
>(
Arrays
.
asList
(
"files"
,
"input"
,
"outputDir"
,
"verbose"
,
"printHelp"
"files"
,
"input"
,
"outputDir"
,
"verbose"
,
"printHelp"
...
@@ -27,6 +28,7 @@ public class JadxSettings extends JadxCLIArgs {
...
@@ -27,6 +28,7 @@ public class JadxSettings extends JadxCLIArgs {
private
boolean
checkForUpdates
=
true
;
private
boolean
checkForUpdates
=
true
;
private
List
<
String
>
recentFiles
=
new
ArrayList
<
String
>();
private
List
<
String
>
recentFiles
=
new
ArrayList
<
String
>();
private
String
fontStr
=
""
;
private
String
fontStr
=
""
;
private
boolean
useFastSearch
=
false
;
public
void
sync
()
{
public
void
sync
()
{
JadxSettingsAdapter
.
store
(
this
);
JadxSettingsAdapter
.
store
(
this
);
...
@@ -73,10 +75,8 @@ public class JadxSettings extends JadxCLIArgs {
...
@@ -73,10 +75,8 @@ public class JadxSettings extends JadxCLIArgs {
}
}
public
void
addRecentFile
(
String
filePath
)
{
public
void
addRecentFile
(
String
filePath
)
{
if
(
recentFiles
.
contains
(
filePath
))
{
recentFiles
.
remove
(
filePath
);
return
;
recentFiles
.
add
(
0
,
filePath
);
}
recentFiles
.
add
(
filePath
);
int
count
=
recentFiles
.
size
();
int
count
=
recentFiles
.
size
();
if
(
count
>
RECENT_FILES_COUNT
)
{
if
(
count
>
RECENT_FILES_COUNT
)
{
recentFiles
.
subList
(
0
,
count
-
RECENT_FILES_COUNT
).
clear
();
recentFiles
.
subList
(
0
,
count
-
RECENT_FILES_COUNT
).
clear
();
...
@@ -136,6 +136,14 @@ public class JadxSettings extends JadxCLIArgs {
...
@@ -136,6 +136,14 @@ public class JadxSettings extends JadxCLIArgs {
this
.
deobfuscationUseSourceNameAsAlias
=
useSourceNameAsAlias
;
this
.
deobfuscationUseSourceNameAsAlias
=
useSourceNameAsAlias
;
}
}
public
boolean
isUseFastSearch
()
{
return
useFastSearch
;
}
public
void
setUseFastSearch
(
boolean
useFastSearch
)
{
this
.
useFastSearch
=
useFastSearch
;
}
public
Font
getFont
()
{
public
Font
getFont
()
{
if
(
fontStr
.
isEmpty
())
{
if
(
fontStr
.
isEmpty
())
{
return
DEFAULT_FONT
;
return
DEFAULT_FONT
;
...
...
jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsAdapter.java
View file @
bc73010d
...
@@ -2,6 +2,7 @@ package jadx.gui.settings;
...
@@ -2,6 +2,7 @@ package jadx.gui.settings;
import
jadx.gui.JadxGUI
;
import
jadx.gui.JadxGUI
;
import
java.lang.reflect.Modifier
;
import
java.lang.reflect.Type
;
import
java.lang.reflect.Type
;
import
java.util.prefs.Preferences
;
import
java.util.prefs.Preferences
;
...
@@ -25,7 +26,9 @@ public class JadxSettingsAdapter {
...
@@ -25,7 +26,9 @@ public class JadxSettingsAdapter {
private
static
ExclusionStrategy
EXCLUDE_FIELDS
=
new
ExclusionStrategy
()
{
private
static
ExclusionStrategy
EXCLUDE_FIELDS
=
new
ExclusionStrategy
()
{
@Override
@Override
public
boolean
shouldSkipField
(
FieldAttributes
f
)
{
public
boolean
shouldSkipField
(
FieldAttributes
f
)
{
return
JadxSettings
.
SKIP_FIELDS
.
contains
(
f
.
getName
());
return
JadxSettings
.
SKIP_FIELDS
.
contains
(
f
.
getName
())
||
f
.
hasModifier
(
Modifier
.
PUBLIC
)
||
f
.
hasModifier
(
Modifier
.
TRANSIENT
);
}
}
@Override
@Override
...
...
jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsWindow.java
View file @
bc73010d
...
@@ -239,6 +239,14 @@ public class JadxSettingsWindow extends JDialog {
...
@@ -239,6 +239,14 @@ public class JadxSettingsWindow extends JDialog {
}
}
});
});
JCheckBox
fastSearch
=
new
JCheckBox
();
fastSearch
.
setSelected
(
settings
.
isUseFastSearch
());
fastSearch
.
addItemListener
(
new
ItemListener
()
{
public
void
itemStateChanged
(
ItemEvent
e
)
{
settings
.
setUseFastSearch
(
e
.
getStateChange
()
==
ItemEvent
.
SELECTED
);
}
});
SettingsGroup
other
=
new
SettingsGroup
(
NLS
.
str
(
"preferences.other"
));
SettingsGroup
other
=
new
SettingsGroup
(
NLS
.
str
(
"preferences.other"
));
other
.
addRow
(
NLS
.
str
(
"preferences.check_for_updates"
),
update
);
other
.
addRow
(
NLS
.
str
(
"preferences.check_for_updates"
),
update
);
other
.
addRow
(
NLS
.
str
(
"preferences.threads"
),
threadsCount
);
other
.
addRow
(
NLS
.
str
(
"preferences.threads"
),
threadsCount
);
...
@@ -248,6 +256,7 @@ public class JadxSettingsWindow extends JDialog {
...
@@ -248,6 +256,7 @@ public class JadxSettingsWindow extends JDialog {
other
.
addRow
(
NLS
.
str
(
"preferences.cfg"
),
cfg
);
other
.
addRow
(
NLS
.
str
(
"preferences.cfg"
),
cfg
);
other
.
addRow
(
NLS
.
str
(
"preferences.raw_cfg"
),
rawCfg
);
other
.
addRow
(
NLS
.
str
(
"preferences.raw_cfg"
),
rawCfg
);
other
.
addRow
(
NLS
.
str
(
"preferences.font"
),
fontBtn
);
other
.
addRow
(
NLS
.
str
(
"preferences.font"
),
fontBtn
);
other
.
addRow
(
NLS
.
str
(
"preferences.fast_search"
),
fastSearch
);
return
other
;
return
other
;
}
}
...
...
jadx-gui/src/main/java/jadx/gui/treemodel/CodeNode.java
View file @
bc73010d
package
jadx
.
gui
.
treemodel
;
package
jadx
.
gui
.
treemodel
;
import
jadx.api.JavaClass
;
import
jadx.api.JavaNode
;
import
jadx.gui.utils.Utils
;
import
javax.swing.Icon
;
import
javax.swing.Icon
;
import
javax.swing.ImageIcon
;
public
class
CodeNode
extends
J
Class
{
public
class
CodeNode
extends
J
Node
{
private
static
final
ImageIcon
ICON
=
Utils
.
openIcon
(
"file_obj"
)
;
private
static
final
long
serialVersionUID
=
1658650786734966545L
;
private
final
JNode
jNode
;
private
final
JClass
jParent
;
private
final
String
line
;
private
final
String
line
;
private
final
int
lineNum
;
private
final
int
lineNum
;
public
CodeNode
(
JavaClass
javaClass
,
int
lineNum
,
String
line
)
{
public
CodeNode
(
JavaNode
javaNode
,
int
lineNum
,
String
line
)
{
super
(
javaClass
,
(
JClass
)
makeFrom
(
javaClass
.
getDeclaringClass
()));
this
.
jNode
=
makeFrom
(
javaNode
);
this
.
jParent
=
jNode
.
getJParent
();
this
.
line
=
line
;
this
.
line
=
line
;
this
.
lineNum
=
lineNum
;
this
.
lineNum
=
lineNum
;
}
}
@Override
@Override
public
Icon
getIcon
()
{
public
Icon
getIcon
()
{
return
ICON
;
return
jNode
.
getIcon
();
}
@Override
public
JavaNode
getJavaNode
()
{
return
jNode
.
getJavaNode
();
}
@Override
public
JClass
getJParent
()
{
return
getRootClass
();
}
@Override
public
JClass
getRootClass
()
{
JClass
parent
=
jParent
;
if
(
parent
!=
null
)
{
return
parent
.
getRootClass
();
}
if
(
jNode
instanceof
JClass
)
{
return
(
JClass
)
jNode
;
}
return
null
;
}
}
@Override
@Override
...
@@ -30,17 +53,22 @@ public class CodeNode extends JClass {
...
@@ -30,17 +53,22 @@ public class CodeNode extends JClass {
}
}
@Override
@Override
public
String
makeString
()
{
public
String
make
Desc
String
()
{
return
getCls
().
getFullName
()
+
":"
+
lineNum
+
" "
+
line
;
return
line
;
}
}
@Override
@Override
public
String
makeLongString
()
{
public
boolean
hasDescString
()
{
return
makeString
();
return
true
;
}
@Override
public
String
makeString
()
{
return
jNode
.
makeLongString
();
}
}
@Override
@Override
public
String
to
String
()
{
public
String
makeLong
String
()
{
return
makeString
();
return
makeString
();
}
}
}
}
jadx-gui/src/main/java/jadx/gui/treemodel/JClass.java
View file @
bc73010d
...
@@ -3,6 +3,7 @@ package jadx.gui.treemodel;
...
@@ -3,6 +3,7 @@ package jadx.gui.treemodel;
import
jadx.api.JavaClass
;
import
jadx.api.JavaClass
;
import
jadx.api.JavaField
;
import
jadx.api.JavaField
;
import
jadx.api.JavaMethod
;
import
jadx.api.JavaMethod
;
import
jadx.api.JavaNode
;
import
jadx.core.dex.info.AccessInfo
;
import
jadx.core.dex.info.AccessInfo
;
import
jadx.gui.utils.NLS
;
import
jadx.gui.utils.NLS
;
import
jadx.gui.utils.Utils
;
import
jadx.gui.utils.Utils
;
...
@@ -104,6 +105,11 @@ public class JClass extends JNode {
...
@@ -104,6 +105,11 @@ public class JClass extends JNode {
}
}
@Override
@Override
public
JavaNode
getJavaNode
()
{
return
cls
;
}
@Override
public
JClass
getJParent
()
{
public
JClass
getJParent
()
{
return
jParent
;
return
jParent
;
}
}
...
@@ -116,6 +122,11 @@ public class JClass extends JNode {
...
@@ -116,6 +122,11 @@ public class JClass extends JNode {
return
jParent
.
getRootClass
();
return
jParent
.
getRootClass
();
}
}
@Override
public
String
getName
()
{
return
cls
.
getName
();
}
public
String
getFullName
()
{
public
String
getFullName
()
{
return
cls
.
getFullName
();
return
cls
.
getFullName
();
}
}
...
...
jadx-gui/src/main/java/jadx/gui/treemodel/JField.java
View file @
bc73010d
package
jadx
.
gui
.
treemodel
;
package
jadx
.
gui
.
treemodel
;
import
jadx.api.JavaField
;
import
jadx.api.JavaField
;
import
jadx.api.JavaNode
;
import
jadx.core.dex.info.AccessInfo
;
import
jadx.core.dex.info.AccessInfo
;
import
jadx.gui.utils.OverlayIcon
;
import
jadx.gui.utils.OverlayIcon
;
import
jadx.gui.utils.Utils
;
import
jadx.gui.utils.Utils
;
...
@@ -28,6 +29,11 @@ public class JField extends JNode {
...
@@ -28,6 +29,11 @@ public class JField extends JNode {
}
}
@Override
@Override
public
JavaNode
getJavaNode
()
{
return
field
;
}
@Override
public
JClass
getJParent
()
{
public
JClass
getJParent
()
{
return
jParent
;
return
jParent
;
}
}
...
@@ -64,4 +70,14 @@ public class JField extends JNode {
...
@@ -64,4 +70,14 @@ public class JField extends JNode {
public
String
makeLongString
()
{
public
String
makeLongString
()
{
return
Utils
.
typeFormat
(
field
.
getFullName
(),
field
.
getType
());
return
Utils
.
typeFormat
(
field
.
getFullName
(),
field
.
getType
());
}
}
@Override
public
int
hashCode
()
{
return
field
.
hashCode
();
}
@Override
public
boolean
equals
(
Object
o
)
{
return
this
==
o
||
o
instanceof
JField
&&
field
.
equals
(((
JField
)
o
).
field
);
}
}
}
jadx-gui/src/main/java/jadx/gui/treemodel/JMethod.java
View file @
bc73010d
package
jadx
.
gui
.
treemodel
;
package
jadx
.
gui
.
treemodel
;
import
jadx.api.JavaMethod
;
import
jadx.api.JavaMethod
;
import
jadx.api.JavaNode
;
import
jadx.core.dex.info.AccessInfo
;
import
jadx.core.dex.info.AccessInfo
;
import
jadx.core.dex.instructions.args.ArgType
;
import
jadx.core.dex.instructions.args.ArgType
;
import
jadx.gui.utils.OverlayIcon
;
import
jadx.gui.utils.OverlayIcon
;
...
@@ -30,10 +31,19 @@ public class JMethod extends JNode {
...
@@ -30,10 +31,19 @@ public class JMethod extends JNode {
}
}
@Override
@Override
public
JavaNode
getJavaNode
()
{
return
mth
;
}
@Override
public
JClass
getJParent
()
{
public
JClass
getJParent
()
{
return
jParent
;
return
jParent
;
}
}
public
ArgType
getReturnType
()
{
return
mth
.
getReturnType
();
}
@Override
@Override
public
JClass
getRootClass
()
{
public
JClass
getRootClass
()
{
return
jParent
.
getRootClass
();
return
jParent
.
getRootClass
();
...
@@ -57,7 +67,7 @@ public class JMethod extends JNode {
...
@@ -57,7 +67,7 @@ public class JMethod extends JNode {
return
icon
;
return
icon
;
}
}
private
String
makeBaseString
()
{
String
makeBaseString
()
{
if
(
mth
.
isClassInit
())
{
if
(
mth
.
isClassInit
())
{
return
"{...}"
;
return
"{...}"
;
}
}
...
@@ -80,12 +90,22 @@ public class JMethod extends JNode {
...
@@ -80,12 +90,22 @@ public class JMethod extends JNode {
@Override
@Override
public
String
makeString
()
{
public
String
makeString
()
{
return
Utils
.
typeFormat
(
makeBaseString
(),
mth
.
getReturnType
());
return
Utils
.
typeFormat
(
makeBaseString
(),
getReturnType
());
}
}
@Override
@Override
public
String
makeLongString
()
{
public
String
makeLongString
()
{
String
name
=
mth
.
getDeclaringClass
().
getFullName
()
+
"."
+
makeBaseString
();
String
name
=
mth
.
getDeclaringClass
().
getFullName
()
+
"."
+
makeBaseString
();
return
Utils
.
typeFormat
(
name
,
mth
.
getReturnType
());
return
Utils
.
typeFormat
(
name
,
getReturnType
());
}
@Override
public
int
hashCode
()
{
return
mth
.
hashCode
();
}
@Override
public
boolean
equals
(
Object
o
)
{
return
this
==
o
||
o
instanceof
JMethod
&&
mth
.
equals
(((
JMethod
)
o
).
mth
);
}
}
}
}
jadx-gui/src/main/java/jadx/gui/treemodel/JNode.java
View file @
bc73010d
...
@@ -13,20 +13,20 @@ import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
...
@@ -13,20 +13,20 @@ import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
public
abstract
class
JNode
extends
DefaultMutableTreeNode
{
public
abstract
class
JNode
extends
DefaultMutableTreeNode
{
public
static
JNode
makeFrom
(
JavaNode
node
)
{
public
static
JNode
makeFrom
(
JavaNode
node
)
{
if
(
node
==
null
)
{
return
null
;
}
if
(
node
instanceof
JavaClass
)
{
if
(
node
instanceof
JavaClass
)
{
JClass
p
=
(
JClass
)
makeFrom
(
node
.
getDeclaringClass
());
JClass
p
=
(
JClass
)
makeFrom
(
node
.
getDeclaringClass
());
return
new
JClass
((
JavaClass
)
node
,
p
);
return
new
JClass
((
JavaClass
)
node
,
p
);
}
}
if
(
node
instanceof
JavaMethod
)
{
if
(
node
instanceof
JavaMethod
)
{
JavaMethod
mth
=
(
JavaMethod
)
node
;
JavaMethod
mth
=
(
JavaMethod
)
node
;
return
new
JMethod
(
mth
,
new
JClass
(
mth
.
getDeclaringClass
()));
return
new
JMethod
(
mth
,
(
JClass
)
makeFrom
(
mth
.
getDeclaringClass
()));
}
}
if
(
node
instanceof
JavaField
)
{
if
(
node
instanceof
JavaField
)
{
JavaField
fld
=
(
JavaField
)
node
;
JavaField
fld
=
(
JavaField
)
node
;
return
new
JField
(
fld
,
new
JClass
(
fld
.
getDeclaringClass
()));
return
new
JField
(
fld
,
(
JClass
)
makeFrom
(
fld
.
getDeclaringClass
()));
}
if
(
node
==
null
)
{
return
null
;
}
}
throw
new
JadxRuntimeException
(
"Unknown type for JavaNode: "
+
node
.
getClass
());
throw
new
JadxRuntimeException
(
"Unknown type for JavaNode: "
+
node
.
getClass
());
}
}
...
@@ -40,6 +40,10 @@ public abstract class JNode extends DefaultMutableTreeNode {
...
@@ -40,6 +40,10 @@ public abstract class JNode extends DefaultMutableTreeNode {
return
null
;
return
null
;
}
}
public
JavaNode
getJavaNode
()
{
return
null
;
}
public
String
getContent
()
{
public
String
getContent
()
{
return
null
;
return
null
;
}
}
...
@@ -58,8 +62,24 @@ public abstract class JNode extends DefaultMutableTreeNode {
...
@@ -58,8 +62,24 @@ public abstract class JNode extends DefaultMutableTreeNode {
public
abstract
Icon
getIcon
();
public
abstract
Icon
getIcon
();
public
String
getName
()
{
JavaNode
javaNode
=
getJavaNode
();
if
(
javaNode
==
null
)
{
return
null
;
}
return
javaNode
.
getName
();
}
public
abstract
String
makeString
();
public
abstract
String
makeString
();
public
String
makeDescString
()
{
return
null
;
}
public
boolean
hasDescString
()
{
return
false
;
}
public
String
makeLongString
()
{
public
String
makeLongString
()
{
return
makeString
();
return
makeString
();
}
}
...
...
jadx-gui/src/main/java/jadx/gui/treemodel/JPackage.java
View file @
bc73010d
...
@@ -9,6 +9,8 @@ import javax.swing.ImageIcon;
...
@@ -9,6 +9,8 @@ import javax.swing.ImageIcon;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.List
;
import
org.jetbrains.annotations.NotNull
;
public
class
JPackage
extends
JNode
implements
Comparable
<
JPackage
>
{
public
class
JPackage
extends
JNode
implements
Comparable
<
JPackage
>
{
private
static
final
long
serialVersionUID
=
-
4120718634156839804L
;
private
static
final
long
serialVersionUID
=
-
4120718634156839804L
;
...
@@ -45,6 +47,7 @@ public class JPackage extends JNode implements Comparable<JPackage> {
...
@@ -45,6 +47,7 @@ public class JPackage extends JNode implements Comparable<JPackage> {
}
}
}
}
@Override
public
String
getName
()
{
public
String
getName
()
{
return
name
;
return
name
;
}
}
...
@@ -77,7 +80,7 @@ public class JPackage extends JNode implements Comparable<JPackage> {
...
@@ -77,7 +80,7 @@ public class JPackage extends JNode implements Comparable<JPackage> {
}
}
@Override
@Override
public
int
compareTo
(
JPackage
o
)
{
public
int
compareTo
(
@NotNull
JPackage
o
)
{
return
name
.
compareTo
(
o
.
name
);
return
name
.
compareTo
(
o
.
name
);
}
}
...
...
jadx-gui/src/main/java/jadx/gui/treemodel/JResource.java
View file @
bc73010d
...
@@ -24,7 +24,7 @@ public class JResource extends JNode implements Comparable<JResource> {
...
@@ -24,7 +24,7 @@ public class JResource extends JNode implements Comparable<JResource> {
private
static
final
ImageIcon
JAVA_ICON
=
Utils
.
openIcon
(
"java_ovr"
);
private
static
final
ImageIcon
JAVA_ICON
=
Utils
.
openIcon
(
"java_ovr"
);
private
static
final
ImageIcon
ERROR_ICON
=
Utils
.
openIcon
(
"error_co"
);
private
static
final
ImageIcon
ERROR_ICON
=
Utils
.
openIcon
(
"error_co"
);
public
static
enum
JResType
{
public
enum
JResType
{
ROOT
,
ROOT
,
DIR
,
DIR
,
FILE
FILE
...
...
jadx-gui/src/main/java/jadx/gui/ui/CommonSearchDialog.java
0 → 100644
View file @
bc73010d
package
jadx
.
gui
.
ui
;
import
jadx.gui.jobs.BackgroundJob
;
import
jadx.gui.jobs.DecompileJob
;
import
jadx.gui.treemodel.JNode
;
import
jadx.gui.treemodel.TextNode
;
import
jadx.gui.utils.CacheObject
;
import
jadx.gui.utils.NLS
;
import
jadx.gui.utils.Position
;
import
jadx.gui.utils.TextSearchIndex
;
import
javax.swing.BorderFactory
;
import
javax.swing.Box
;
import
javax.swing.BoxLayout
;
import
javax.swing.JButton
;
import
javax.swing.JComponent
;
import
javax.swing.JDialog
;
import
javax.swing.JLabel
;
import
javax.swing.JPanel
;
import
javax.swing.JScrollPane
;
import
javax.swing.JTable
;
import
javax.swing.KeyStroke
;
import
javax.swing.ListSelectionModel
;
import
javax.swing.ScrollPaneConstants
;
import
javax.swing.SwingWorker
;
import
javax.swing.UIDefaults
;
import
javax.swing.UIManager
;
import
javax.swing.table.AbstractTableModel
;
import
javax.swing.table.TableCellRenderer
;
import
javax.swing.table.TableColumn
;
import
javax.swing.table.TableColumnModel
;
import
java.awt.Color
;
import
java.awt.Component
;
import
java.awt.Cursor
;
import
java.awt.Dimension
;
import
java.awt.Font
;
import
java.awt.event.ActionEvent
;
import
java.awt.event.ActionListener
;
import
java.awt.event.KeyAdapter
;
import
java.awt.event.KeyEvent
;
import
java.awt.event.MouseAdapter
;
import
java.awt.event.MouseEvent
;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.fife.ui.rsyntaxtextarea.RSyntaxTextArea
;
import
org.fife.ui.rsyntaxtextarea.SyntaxConstants
;
import
org.fife.ui.rtextarea.SearchContext
;
import
org.fife.ui.rtextarea.SearchEngine
;
import
org.jetbrains.annotations.NotNull
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
public
abstract
class
CommonSearchDialog
extends
JDialog
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
CommonSearchDialog
.
class
);
private
static
final
long
serialVersionUID
=
8939332306115370276L
;
public
static
final
int
MAX_RESULTS_COUNT
=
1000
;
protected
final
TabbedPane
tabbedPane
;
protected
final
CacheObject
cache
;
protected
final
MainWindow
mainWindow
;
protected
final
Font
codeFont
;
protected
ResultsModel
resultsModel
;
protected
ResultsTable
resultsTable
;
protected
JLabel
warnLabel
;
protected
ProgressPanel
progressPane
;
protected
String
highlightText
;
public
CommonSearchDialog
(
MainWindow
mainWindow
)
{
super
(
mainWindow
);
this
.
mainWindow
=
mainWindow
;
this
.
tabbedPane
=
mainWindow
.
getTabbedPane
();
this
.
cache
=
mainWindow
.
getCacheObject
();
this
.
codeFont
=
mainWindow
.
getSettings
().
getFont
();
}
public
void
prepare
()
{
if
(
cache
.
getIndexJob
().
isComplete
())
{
loadFinishedCommon
();
loadFinished
();
return
;
}
LoadTask
task
=
new
LoadTask
();
task
.
addPropertyChangeListener
(
progressPane
);
task
.
execute
();
}
protected
void
openSelectedItem
()
{
int
selectedId
=
resultsTable
.
getSelectedRow
();
if
(
selectedId
==
-
1
)
{
return
;
}
JNode
node
=
(
JNode
)
resultsModel
.
getValueAt
(
selectedId
,
0
);
tabbedPane
.
codeJump
(
new
Position
(
node
.
getRootClass
(),
node
.
getLine
()));
dispose
();
}
protected
void
initCommon
()
{
KeyStroke
stroke
=
KeyStroke
.
getKeyStroke
(
KeyEvent
.
VK_ESCAPE
,
0
);
getRootPane
().
registerKeyboardAction
(
new
ActionListener
()
{
@Override
public
void
actionPerformed
(
ActionEvent
e
)
{
dispose
();
}
},
stroke
,
JComponent
.
WHEN_IN_FOCUSED_WINDOW
);
}
@NotNull
protected
JPanel
initButtonsPanel
()
{
progressPane
=
new
ProgressPanel
(
mainWindow
,
false
);
JButton
cancelButton
=
new
JButton
(
NLS
.
str
(
"search_dialog.cancel"
));
cancelButton
.
addActionListener
(
new
ActionListener
()
{
public
void
actionPerformed
(
ActionEvent
event
)
{
dispose
();
}
});
JButton
openBtn
=
new
JButton
(
NLS
.
str
(
"search_dialog.open"
));
openBtn
.
addActionListener
(
new
ActionListener
()
{
public
void
actionPerformed
(
ActionEvent
event
)
{
openSelectedItem
();
}
});
getRootPane
().
setDefaultButton
(
openBtn
);
JPanel
buttonPane
=
new
JPanel
();
buttonPane
.
setLayout
(
new
BoxLayout
(
buttonPane
,
BoxLayout
.
LINE_AXIS
));
buttonPane
.
setBorder
(
BorderFactory
.
createEmptyBorder
(
0
,
10
,
10
,
10
));
buttonPane
.
add
(
progressPane
);
buttonPane
.
add
(
Box
.
createRigidArea
(
new
Dimension
(
5
,
0
)));
buttonPane
.
add
(
Box
.
createHorizontalGlue
());
buttonPane
.
add
(
openBtn
);
buttonPane
.
add
(
Box
.
createRigidArea
(
new
Dimension
(
10
,
0
)));
buttonPane
.
add
(
cancelButton
);
return
buttonPane
;
}
protected
JPanel
initResultsTable
()
{
resultsModel
=
new
ResultsModel
();
resultsTable
=
new
ResultsTable
(
resultsModel
);
resultsTable
.
setShowHorizontalLines
(
false
);
// resultsTable.setAutoCreateColumnsFromModel(true);
resultsTable
.
setDragEnabled
(
false
);
resultsTable
.
setSelectionMode
(
ListSelectionModel
.
SINGLE_SELECTION
);
resultsTable
.
setBackground
(
ContentArea
.
BACKGROUND
);
resultsTable
.
setColumnSelectionAllowed
(
false
);
resultsTable
.
setAutoResizeMode
(
JTable
.
AUTO_RESIZE_OFF
);
resultsTable
.
setAutoscrolls
(
false
);
resultsTable
.
setDefaultRenderer
(
Object
.
class
,
new
ResultsTableCellRenderer
());
resultsTable
.
addMouseListener
(
new
MouseAdapter
()
{
public
void
mouseClicked
(
MouseEvent
evt
)
{
if
(
evt
.
getClickCount
()
==
2
)
{
openSelectedItem
();
}
}
});
resultsTable
.
addKeyListener
(
new
KeyAdapter
()
{
@Override
public
void
keyPressed
(
KeyEvent
e
)
{
if
(
e
.
getKeyCode
()
==
KeyEvent
.
VK_ENTER
)
{
openSelectedItem
();
}
}
});
warnLabel
=
new
JLabel
();
warnLabel
.
setForeground
(
Color
.
RED
);
warnLabel
.
setVisible
(
false
);
JPanel
resultsPanel
=
new
JPanel
();
resultsPanel
.
setLayout
(
new
BoxLayout
(
resultsPanel
,
BoxLayout
.
PAGE_AXIS
));
resultsPanel
.
add
(
warnLabel
);
resultsPanel
.
add
(
new
JScrollPane
(
resultsTable
,
ScrollPaneConstants
.
VERTICAL_SCROLLBAR_AS_NEEDED
,
ScrollPaneConstants
.
HORIZONTAL_SCROLLBAR_AS_NEEDED
));
resultsPanel
.
setBorder
(
BorderFactory
.
createEmptyBorder
(
0
,
10
,
10
,
10
));
return
resultsPanel
;
}
protected
static
class
ResultsTable
extends
JTable
{
private
static
final
long
serialVersionUID
=
3901184054736618969L
;
public
ResultsTable
(
ResultsModel
resultsModel
)
{
super
(
resultsModel
);
}
public
void
updateTable
()
{
ResultsModel
model
=
(
ResultsModel
)
getModel
();
TableColumnModel
columnModel
=
getColumnModel
();
int
width
=
getParent
().
getWidth
();
int
firstColMaxWidth
=
(
int
)
(
width
*
0.5
);
int
rowCount
=
getRowCount
();
int
columnCount
=
getColumnCount
();
if
(!
model
.
isAddDescColumn
())
{
firstColMaxWidth
=
width
;
}
Component
codeComp
=
null
;
for
(
int
col
=
0
;
col
<
columnCount
;
col
++)
{
int
colWidth
=
50
;
for
(
int
row
=
0
;
row
<
rowCount
;
row
++)
{
TableCellRenderer
renderer
=
getCellRenderer
(
row
,
col
);
Component
comp
=
prepareRenderer
(
renderer
,
row
,
col
);
if
(
comp
==
null
)
{
continue
;
}
colWidth
=
Math
.
max
(
comp
.
getPreferredSize
().
width
,
colWidth
);
if
(
codeComp
==
null
&&
col
==
1
)
{
codeComp
=
comp
;
}
}
colWidth
+=
10
;
if
(
col
==
0
)
{
colWidth
=
Math
.
min
(
colWidth
,
firstColMaxWidth
);
}
else
{
colWidth
=
Math
.
max
(
colWidth
,
width
-
columnModel
.
getColumn
(
0
).
getPreferredWidth
());
}
TableColumn
column
=
columnModel
.
getColumn
(
col
);
column
.
setPreferredWidth
(
colWidth
);
}
if
(
codeComp
!=
null
)
{
setRowHeight
(
codeComp
.
getPreferredSize
().
height
+
4
);
}
updateUI
();
}
}
protected
static
class
ResultsModel
extends
AbstractTableModel
{
private
static
final
long
serialVersionUID
=
-
7821286846923903208L
;
private
static
final
String
[]
COLUMN_NAMES
=
{
"Node"
,
"Code"
};
private
final
List
<
JNode
>
rows
=
new
ArrayList
<
JNode
>();
private
boolean
addDescColumn
;
protected
void
addAll
(
Iterable
<?
extends
JNode
>
nodes
)
{
for
(
JNode
node
:
nodes
)
{
int
size
=
getRowCount
();
if
(
size
>=
MAX_RESULTS_COUNT
)
{
if
(
size
==
MAX_RESULTS_COUNT
)
{
add
(
new
TextNode
(
"Search results truncated (limit: "
+
MAX_RESULTS_COUNT
+
")"
));
}
return
;
}
add
(
node
);
}
}
private
void
add
(
JNode
node
)
{
if
(
node
.
hasDescString
())
{
addDescColumn
=
true
;
}
rows
.
add
(
node
);
}
public
void
clear
()
{
addDescColumn
=
false
;
rows
.
clear
();
}
public
boolean
isAddDescColumn
()
{
return
addDescColumn
;
}
@Override
public
int
getRowCount
()
{
return
rows
.
size
();
}
@Override
public
int
getColumnCount
()
{
return
2
;
}
@Override
public
String
getColumnName
(
int
index
)
{
return
COLUMN_NAMES
[
index
];
}
@Override
public
Object
getValueAt
(
int
rowIndex
,
int
columnIndex
)
{
return
rows
.
get
(
rowIndex
);
}
}
protected
class
ResultsTableCellRenderer
implements
TableCellRenderer
{
private
final
Color
selectedBackground
;
private
final
Color
selectedForeground
;
ResultsTableCellRenderer
()
{
UIDefaults
defaults
=
UIManager
.
getDefaults
();
selectedBackground
=
defaults
.
getColor
(
"List.selectionBackground"
);
selectedForeground
=
defaults
.
getColor
(
"List.selectionForeground"
);
}
@Override
public
Component
getTableCellRendererComponent
(
JTable
table
,
Object
obj
,
boolean
isSelected
,
boolean
hasFocus
,
int
row
,
int
column
)
{
if
(!(
obj
instanceof
JNode
))
{
return
null
;
}
JNode
node
=
(
JNode
)
obj
;
if
(
column
==
0
)
{
JLabel
label
=
new
JLabel
();
label
.
setOpaque
(
true
);
if
(
isSelected
)
{
label
.
setBackground
(
selectedBackground
);
label
.
setForeground
(
selectedForeground
);
}
else
{
label
.
setBackground
(
ContentArea
.
BACKGROUND
);
}
label
.
setIcon
(
node
.
getIcon
());
label
.
setText
(
node
.
makeLongString
()
+
" "
);
return
label
;
}
if
(
node
.
hasDescString
())
{
RSyntaxTextArea
textArea
=
new
RSyntaxTextArea
();
textArea
.
setFont
(
codeFont
);
textArea
.
setEditable
(
false
);
textArea
.
setSyntaxEditingStyle
(
SyntaxConstants
.
SYNTAX_STYLE_JAVA
);
textArea
.
setBackground
(
isSelected
?
selectedBackground
:
ContentArea
.
BACKGROUND
);
textArea
.
setText
(
" "
+
node
.
makeDescString
());
textArea
.
setRows
(
1
);
textArea
.
setColumns
(
textArea
.
getText
().
length
());
if
(
highlightText
!=
null
)
{
SearchEngine
.
markAll
(
textArea
,
new
SearchContext
(
highlightText
));
}
return
textArea
;
}
return
null
;
}
}
private
class
LoadTask
extends
SwingWorker
<
Void
,
Void
>
{
public
LoadTask
()
{
loadStartCommon
();
loadStart
();
}
@Override
public
Void
doInBackground
()
{
try
{
mainWindow
.
getBackgroundWorker
().
exec
();
DecompileJob
decompileJob
=
cache
.
getDecompileJob
();
progressPane
.
changeLabel
(
this
,
decompileJob
.
getInfoString
());
decompileJob
.
processAndWait
();
BackgroundJob
indexJob
=
cache
.
getIndexJob
();
progressPane
.
changeLabel
(
this
,
indexJob
.
getInfoString
());
indexJob
.
processAndWait
();
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Waiting background tasks failed"
,
e
);
}
return
null
;
}
@Override
public
void
done
()
{
loadFinishedCommon
();
loadFinished
();
}
}
protected
void
loadStartCommon
()
{
setCursor
(
Cursor
.
getPredefinedCursor
(
Cursor
.
WAIT_CURSOR
));
progressPane
.
setIndeterminate
(
true
);
progressPane
.
setVisible
(
true
);
resultsTable
.
setEnabled
(
false
);
warnLabel
.
setVisible
(
false
);
}
private
void
loadFinishedCommon
()
{
setCursor
(
null
);
resultsTable
.
setEnabled
(
true
);
progressPane
.
setVisible
(
false
);
TextSearchIndex
textIndex
=
cache
.
getTextIndex
();
if
(
textIndex
==
null
)
{
warnLabel
.
setText
(
"Index not initialized, search will be disabled!"
);
warnLabel
.
setVisible
(
true
);
}
}
protected
abstract
void
loadFinished
();
protected
abstract
void
loadStart
();
}
jadx-gui/src/main/java/jadx/gui/ui/ContentArea.java
View file @
bc73010d
package
jadx
.
gui
.
ui
;
package
jadx
.
gui
.
ui
;
import
jadx.api.CodePosition
;
import
jadx.api.CodePosition
;
import
jadx.api.JavaNode
;
import
jadx.gui.settings.JadxSettings
;
import
jadx.gui.settings.JadxSettings
;
import
jadx.gui.treemodel.JClass
;
import
jadx.gui.treemodel.JClass
;
import
jadx.gui.treemodel.JNode
;
import
jadx.gui.treemodel.JNode
;
import
jadx.gui.utils.Position
;
import
jadx.gui.utils.Position
;
import
javax.swing.AbstractAction
;
import
javax.swing.Action
;
import
javax.swing.JPopupMenu
;
import
javax.swing.JViewport
;
import
javax.swing.JViewport
;
import
javax.swing.SwingUtilities
;
import
javax.swing.SwingUtilities
;
import
javax.swing.event.HyperlinkEvent
;
import
javax.swing.event.HyperlinkEvent
;
import
javax.swing.event.HyperlinkListener
;
import
javax.swing.event.HyperlinkListener
;
import
javax.swing.event.PopupMenuEvent
;
import
javax.swing.event.PopupMenuListener
;
import
javax.swing.text.BadLocationException
;
import
javax.swing.text.BadLocationException
;
import
javax.swing.text.Caret
;
import
javax.swing.text.Caret
;
import
javax.swing.text.DefaultCaret
;
import
javax.swing.text.DefaultCaret
;
...
@@ -17,6 +23,7 @@ import java.awt.Color;
...
@@ -17,6 +23,7 @@ import java.awt.Color;
import
java.awt.Dimension
;
import
java.awt.Dimension
;
import
java.awt.Point
;
import
java.awt.Point
;
import
java.awt.Rectangle
;
import
java.awt.Rectangle
;
import
java.awt.event.ActionEvent
;
import
org.fife.ui.rsyntaxtextarea.LinkGenerator
;
import
org.fife.ui.rsyntaxtextarea.LinkGenerator
;
import
org.fife.ui.rsyntaxtextarea.LinkGeneratorResult
;
import
org.fife.ui.rsyntaxtextarea.LinkGeneratorResult
;
...
@@ -63,11 +70,23 @@ class ContentArea extends RSyntaxTextArea {
...
@@ -63,11 +70,23 @@ class ContentArea extends RSyntaxTextArea {
CodeLinkGenerator
codeLinkProcessor
=
new
CodeLinkGenerator
((
JClass
)
node
);
CodeLinkGenerator
codeLinkProcessor
=
new
CodeLinkGenerator
((
JClass
)
node
);
setLinkGenerator
(
codeLinkProcessor
);
setLinkGenerator
(
codeLinkProcessor
);
addHyperlinkListener
(
codeLinkProcessor
);
addHyperlinkListener
(
codeLinkProcessor
);
addMenuItems
(
this
,
(
JClass
)
node
);
}
}
setText
(
node
.
getContent
());
setText
(
node
.
getContent
());
}
}
private
void
addMenuItems
(
ContentArea
contentArea
,
JClass
jCls
)
{
Action
findUsage
=
new
FindUsageAction
(
contentArea
,
jCls
);
// TODO: hotkey works only when popup menu is shown
// findUsage.putValue(Action.ACCELERATOR_KEY, getKeyStroke(KeyEvent.VK_F7, KeyEvent.ALT_DOWN_MASK));
JPopupMenu
popup
=
getPopupMenu
();
popup
.
addSeparator
();
popup
.
add
(
findUsage
);
popup
.
addPopupMenuListener
((
PopupMenuListener
)
findUsage
);
}
public
void
loadSettings
()
{
public
void
loadSettings
()
{
JadxSettings
settings
=
contentPanel
.
getTabbedPane
().
getMainWindow
().
getSettings
();
JadxSettings
settings
=
contentPanel
.
getTabbedPane
().
getMainWindow
().
getSettings
();
setFont
(
settings
.
getFont
());
setFont
(
settings
.
getFont
());
...
@@ -83,7 +102,7 @@ class ContentArea extends RSyntaxTextArea {
...
@@ -83,7 +102,7 @@ class ContentArea extends RSyntaxTextArea {
}
}
}
}
if
(
node
instanceof
JClass
)
{
if
(
node
instanceof
JClass
)
{
Position
pos
=
getPosition
((
JClass
)
node
,
this
,
token
.
getOffset
());
Position
pos
=
get
Def
Position
((
JClass
)
node
,
this
,
token
.
getOffset
());
if
(
pos
!=
null
)
{
if
(
pos
!=
null
)
{
return
true
;
return
true
;
}
}
...
@@ -100,21 +119,30 @@ class ContentArea extends RSyntaxTextArea {
...
@@ -100,21 +119,30 @@ class ContentArea extends RSyntaxTextArea {
return
super
.
getForegroundForToken
(
t
);
return
super
.
getForegroundForToken
(
t
);
}
}
static
Position
getPosition
(
JClass
jCls
,
RSyntaxTextArea
textArea
,
int
offset
)
{
static
Position
getDefPosition
(
JClass
jCls
,
RSyntaxTextArea
textArea
,
int
offset
)
{
JavaNode
node
=
getJavaNodeAtOffset
(
jCls
,
textArea
,
offset
);
if
(
node
==
null
)
{
return
null
;
}
CodePosition
pos
=
jCls
.
getCls
().
getDefinitionPosition
(
node
);
if
(
pos
==
null
)
{
return
null
;
}
return
new
Position
(
pos
);
}
static
JavaNode
getJavaNodeAtOffset
(
JClass
jCls
,
RSyntaxTextArea
textArea
,
int
offset
)
{
try
{
try
{
int
line
=
textArea
.
getLineOfOffset
(
offset
);
int
line
=
textArea
.
getLineOfOffset
(
offset
);
int
lineOffset
=
offset
-
textArea
.
getLineStartOffset
(
line
);
int
lineOffset
=
offset
-
textArea
.
getLineStartOffset
(
line
);
CodePosition
pos
=
jCls
.
getCls
().
getDefinitionPosition
(
line
+
1
,
lineOffset
+
1
);
return
jCls
.
getCls
().
getJavaNodeAtPosition
(
line
+
1
,
lineOffset
+
1
);
if
(
pos
!=
null
&&
pos
.
isSet
())
{
return
new
Position
(
pos
);
}
}
catch
(
BadLocationException
e
)
{
}
catch
(
BadLocationException
e
)
{
LOG
.
error
(
"Can't get
lin
e by offset"
,
e
);
LOG
.
error
(
"Can't get
java nod
e by offset"
,
e
);
}
}
return
null
;
return
null
;
}
}
Position
getCurrentPosition
()
{
public
Position
getCurrentPosition
()
{
return
new
Position
(
node
,
getCaretLineNumber
()
+
1
);
return
new
Position
(
node
,
getCaretLineNumber
()
+
1
);
}
}
...
@@ -166,6 +194,52 @@ class ContentArea extends RSyntaxTextArea {
...
@@ -166,6 +194,52 @@ class ContentArea extends RSyntaxTextArea {
}
}
}
}
private
class
FindUsageAction
extends
AbstractAction
implements
PopupMenuListener
{
private
static
final
long
serialVersionUID
=
4692546569977976384L
;
private
final
ContentArea
contentArea
;
private
final
JClass
jCls
;
private
JavaNode
node
;
public
FindUsageAction
(
ContentArea
contentArea
,
JClass
jCls
)
{
super
(
"Find Usage"
);
this
.
contentArea
=
contentArea
;
this
.
jCls
=
jCls
;
}
@Override
public
void
actionPerformed
(
ActionEvent
e
)
{
if
(
node
==
null
)
{
return
;
}
MainWindow
mainWindow
=
contentPanel
.
getTabbedPane
().
getMainWindow
();
UsageDialog
usageDialog
=
new
UsageDialog
(
mainWindow
,
JNode
.
makeFrom
(
node
));
usageDialog
.
setVisible
(
true
);
}
@Override
public
void
popupMenuWillBecomeVisible
(
PopupMenuEvent
e
)
{
node
=
null
;
Point
pos
=
contentArea
.
getMousePosition
();
if
(
pos
!=
null
)
{
Token
token
=
contentArea
.
viewToToken
(
pos
);
if
(
token
!=
null
)
{
node
=
getJavaNodeAtOffset
(
jCls
,
contentArea
,
token
.
getOffset
());
}
}
setEnabled
(
node
!=
null
);
}
@Override
public
void
popupMenuWillBecomeInvisible
(
PopupMenuEvent
e
)
{
}
@Override
public
void
popupMenuCanceled
(
PopupMenuEvent
e
)
{
}
}
private
class
CodeLinkGenerator
implements
LinkGenerator
,
HyperlinkListener
{
private
class
CodeLinkGenerator
implements
LinkGenerator
,
HyperlinkListener
{
private
final
JClass
jCls
;
private
final
JClass
jCls
;
...
@@ -181,7 +255,7 @@ class ContentArea extends RSyntaxTextArea {
...
@@ -181,7 +255,7 @@ class ContentArea extends RSyntaxTextArea {
return
null
;
return
null
;
}
}
final
int
sourceOffset
=
token
.
getOffset
();
final
int
sourceOffset
=
token
.
getOffset
();
final
Position
defPos
=
getPosition
(
jCls
,
textArea
,
sourceOffset
);
final
Position
defPos
=
get
Def
Position
(
jCls
,
textArea
,
sourceOffset
);
if
(
defPos
==
null
)
{
if
(
defPos
==
null
)
{
return
null
;
return
null
;
}
}
...
@@ -207,12 +281,7 @@ class ContentArea extends RSyntaxTextArea {
...
@@ -207,12 +281,7 @@ class ContentArea extends RSyntaxTextArea {
public
void
hyperlinkUpdate
(
HyperlinkEvent
e
)
{
public
void
hyperlinkUpdate
(
HyperlinkEvent
e
)
{
Object
obj
=
e
.
getSource
();
Object
obj
=
e
.
getSource
();
if
(
obj
instanceof
Position
)
{
if
(
obj
instanceof
Position
)
{
Position
pos
=
(
Position
)
obj
;
contentPanel
.
getTabbedPane
().
codeJump
((
Position
)
obj
);
LOG
.
debug
(
"Code jump to: {}"
,
pos
);
TabbedPane
tabbedPane
=
contentPanel
.
getTabbedPane
();
tabbedPane
.
getJumpManager
().
addPosition
(
getCurrentPosition
());
tabbedPane
.
getJumpManager
().
addPosition
(
pos
);
tabbedPane
.
showCode
(
pos
);
}
}
}
}
}
}
...
...
jadx-gui/src/main/java/jadx/gui/ui/MainDropTarget.java
View file @
bc73010d
...
@@ -23,7 +23,6 @@ public class MainDropTarget implements DropTargetListener {
...
@@ -23,7 +23,6 @@ public class MainDropTarget implements DropTargetListener {
private
final
MainWindow
mainWindow
;
private
final
MainWindow
mainWindow
;
public
MainDropTarget
(
MainWindow
mainWindow
)
{
public
MainDropTarget
(
MainWindow
mainWindow
)
{
super
();
this
.
mainWindow
=
mainWindow
;
this
.
mainWindow
=
mainWindow
;
}
}
...
@@ -50,6 +49,7 @@ public class MainDropTarget implements DropTargetListener {
...
@@ -50,6 +49,7 @@ public class MainDropTarget implements DropTargetListener {
}
}
@Override
@Override
@SuppressWarnings
(
"unchecked"
)
public
void
drop
(
DropTargetDropEvent
dtde
)
{
public
void
drop
(
DropTargetDropEvent
dtde
)
{
if
(!
dtde
.
isDataFlavorSupported
(
DataFlavor
.
javaFileListFlavor
))
{
if
(!
dtde
.
isDataFlavorSupported
(
DataFlavor
.
javaFileListFlavor
))
{
dtde
.
rejectDrop
();
dtde
.
rejectDrop
();
...
@@ -57,7 +57,6 @@ public class MainDropTarget implements DropTargetListener {
...
@@ -57,7 +57,6 @@ public class MainDropTarget implements DropTargetListener {
}
}
dtde
.
acceptDrop
(
dtde
.
getDropAction
());
dtde
.
acceptDrop
(
dtde
.
getDropAction
());
try
{
try
{
Transferable
transferable
=
dtde
.
getTransferable
();
Transferable
transferable
=
dtde
.
getTransferable
();
List
<
File
>
transferData
=
(
List
<
File
>)
transferable
.
getTransferData
(
DataFlavor
.
javaFileListFlavor
);
List
<
File
>
transferData
=
(
List
<
File
>)
transferable
.
getTransferData
(
DataFlavor
.
javaFileListFlavor
);
if
(
transferData
!=
null
&&
transferData
.
size
()
>
0
)
{
if
(
transferData
!=
null
&&
transferData
.
size
()
>
0
)
{
...
@@ -65,7 +64,6 @@ public class MainDropTarget implements DropTargetListener {
...
@@ -65,7 +64,6 @@ public class MainDropTarget implements DropTargetListener {
// load first file
// load first file
mainWindow
.
openFile
(
transferData
.
get
(
0
));
mainWindow
.
openFile
(
transferData
.
get
(
0
));
}
}
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
LOG
.
error
(
"File drop operation failed"
,
e
);
LOG
.
error
(
"File drop operation failed"
,
e
);
}
}
...
@@ -73,7 +71,5 @@ public class MainDropTarget implements DropTargetListener {
...
@@ -73,7 +71,5 @@ public class MainDropTarget implements DropTargetListener {
@Override
@Override
public
void
dragExit
(
DropTargetEvent
dte
)
{
public
void
dragExit
(
DropTargetEvent
dte
)
{
}
}
}
}
jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
View file @
bc73010d
package
jadx
.
gui
.
ui
;
package
jadx
.
gui
.
ui
;
import
jadx.gui.JadxWrapper
;
import
jadx.gui.JadxWrapper
;
import
jadx.gui.jobs.BackgroundWorker
;
import
jadx.gui.jobs.DecompileJob
;
import
jadx.gui.jobs.IndexJob
;
import
jadx.gui.settings.JadxSettings
;
import
jadx.gui.settings.JadxSettings
;
import
jadx.gui.settings.JadxSettingsWindow
;
import
jadx.gui.settings.JadxSettingsWindow
;
import
jadx.gui.treemodel.JClass
;
import
jadx.gui.treemodel.JClass
;
...
@@ -48,7 +51,6 @@ import javax.swing.tree.ExpandVetoException;
...
@@ -48,7 +51,6 @@ import javax.swing.tree.ExpandVetoException;
import
javax.swing.tree.TreeNode
;
import
javax.swing.tree.TreeNode
;
import
javax.swing.tree.TreePath
;
import
javax.swing.tree.TreePath
;
import
javax.swing.tree.TreeSelectionModel
;
import
javax.swing.tree.TreeSelectionModel
;
import
java.awt.BorderLayout
;
import
java.awt.BorderLayout
;
import
java.awt.Component
;
import
java.awt.Component
;
import
java.awt.DisplayMode
;
import
java.awt.DisplayMode
;
...
@@ -66,6 +68,8 @@ import java.awt.event.MouseEvent;
...
@@ -66,6 +68,8 @@ import java.awt.event.MouseEvent;
import
java.io.File
;
import
java.io.File
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.EnumSet
;
import
java.util.EnumSet
;
import
java.util.Timer
;
import
java.util.TimerTask
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
...
@@ -111,7 +115,9 @@ public class MainWindow extends JFrame {
...
@@ -111,7 +115,9 @@ public class MainWindow extends JFrame {
private
JToggleButton
deobfToggleBtn
;
private
JToggleButton
deobfToggleBtn
;
private
boolean
isFlattenPackage
;
private
boolean
isFlattenPackage
;
private
Link
updateLink
;
private
Link
updateLink
;
private
ProgressPanel
progressPane
;
private
BackgroundWorker
backgroundWorker
;
private
DropTarget
dropTarget
;
private
DropTarget
dropTarget
;
public
MainWindow
(
JadxSettings
settings
)
{
public
MainWindow
(
JadxSettings
settings
)
{
...
@@ -119,6 +125,7 @@ public class MainWindow extends JFrame {
...
@@ -119,6 +125,7 @@ public class MainWindow extends JFrame {
this
.
settings
=
settings
;
this
.
settings
=
settings
;
this
.
cacheObject
=
new
CacheObject
();
this
.
cacheObject
=
new
CacheObject
();
resetCache
();
initUI
();
initUI
();
initMenuAndToolbar
();
initMenuAndToolbar
();
checkForUpdate
();
checkForUpdate
();
...
@@ -175,18 +182,45 @@ public class MainWindow extends JFrame {
...
@@ -175,18 +182,45 @@ public class MainWindow extends JFrame {
}
}
public
void
openFile
(
File
file
)
{
public
void
openFile
(
File
file
)
{
cacheObject
.
reset
();
tabbedPane
.
closeAllTabs
();
resetCache
();
wrapper
.
openFile
(
file
);
wrapper
.
openFile
(
file
);
deobfToggleBtn
.
setSelected
(
settings
.
isDeobfuscationOn
());
deobfToggleBtn
.
setSelected
(
settings
.
isDeobfuscationOn
());
settings
.
addRecentFile
(
file
.
getAbsolutePath
());
settings
.
addRecentFile
(
file
.
getAbsolutePath
());
initTree
();
initTree
();
setTitle
(
DEFAULT_TITLE
+
" - "
+
file
.
getName
());
setTitle
(
DEFAULT_TITLE
+
" - "
+
file
.
getName
());
runBackgroundJobs
();
}
protected
void
resetCache
()
{
cacheObject
.
reset
();
int
threadsCount
=
settings
.
getThreadsCount
();
cacheObject
.
setDecompileJob
(
new
DecompileJob
(
wrapper
,
threadsCount
));
cacheObject
.
setIndexJob
(
new
IndexJob
(
wrapper
,
settings
,
cacheObject
));
}
private
synchronized
void
runBackgroundJobs
()
{
cancelBackgroundJobs
();
backgroundWorker
=
new
BackgroundWorker
(
cacheObject
,
progressPane
);
new
Timer
().
schedule
(
new
TimerTask
()
{
@Override
public
void
run
()
{
backgroundWorker
.
exec
();
}
},
1000
);
}
public
synchronized
void
cancelBackgroundJobs
()
{
if
(
backgroundWorker
!=
null
)
{
backgroundWorker
.
stop
();
backgroundWorker
=
new
BackgroundWorker
(
cacheObject
,
progressPane
);
resetCache
();
}
}
}
public
void
reOpenFile
()
{
public
void
reOpenFile
()
{
File
openedFile
=
wrapper
.
getOpenFile
();
File
openedFile
=
wrapper
.
getOpenFile
();
if
(
openedFile
!=
null
)
{
if
(
openedFile
!=
null
)
{
tabbedPane
.
closeAllTabs
();
openFile
(
openedFile
);
openFile
(
openedFile
);
}
}
}
}
...
@@ -247,14 +281,14 @@ public class MainWindow extends JFrame {
...
@@ -247,14 +281,14 @@ public class MainWindow extends JFrame {
if
(
obj
instanceof
JResource
)
{
if
(
obj
instanceof
JResource
)
{
JResource
res
=
(
JResource
)
obj
;
JResource
res
=
(
JResource
)
obj
;
if
(
res
.
getContent
()
!=
null
)
{
if
(
res
.
getContent
()
!=
null
)
{
tabbedPane
.
showCode
(
new
Position
(
res
,
res
.
getLine
()));
tabbedPane
.
codeJump
(
new
Position
(
res
,
res
.
getLine
()));
}
}
}
}
if
(
obj
instanceof
JNode
)
{
if
(
obj
instanceof
JNode
)
{
JNode
node
=
(
JNode
)
obj
;
JNode
node
=
(
JNode
)
obj
;
JClass
cls
=
node
.
getRootClass
();
JClass
cls
=
node
.
getRootClass
();
if
(
cls
!=
null
)
{
if
(
cls
!=
null
)
{
tabbedPane
.
showCode
(
new
Position
(
cls
,
node
.
getLine
()));
tabbedPane
.
codeJump
(
new
Position
(
cls
,
node
.
getLine
()));
}
}
}
}
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
...
@@ -539,14 +573,18 @@ public class MainWindow extends JFrame {
...
@@ -539,14 +573,18 @@ public class MainWindow extends JFrame {
}
}
});
});
JScrollPane
treeScrollPane
=
new
JScrollPane
(
tree
);
progressPane
=
new
ProgressPanel
(
this
,
true
);
splitPane
.
setLeftComponent
(
treeScrollPane
);
JPanel
leftPane
=
new
JPanel
(
new
BorderLayout
());
leftPane
.
add
(
new
JScrollPane
(
tree
),
BorderLayout
.
CENTER
);
leftPane
.
add
(
progressPane
,
BorderLayout
.
PAGE_END
);
splitPane
.
setLeftComponent
(
leftPane
);
tabbedPane
=
new
TabbedPane
(
this
);
tabbedPane
=
new
TabbedPane
(
this
);
splitPane
.
setRightComponent
(
tabbedPane
);
splitPane
.
setRightComponent
(
tabbedPane
);
dropTarget
=
new
DropTarget
(
this
,
DnDConstants
.
ACTION_COPY
,
new
MainDropTarget
(
this
));
dropTarget
=
new
DropTarget
(
this
,
DnDConstants
.
ACTION_COPY
,
new
MainDropTarget
(
this
));
setContentPane
(
mainPanel
);
setContentPane
(
mainPanel
);
setTitle
(
DEFAULT_TITLE
);
setTitle
(
DEFAULT_TITLE
);
}
}
...
@@ -565,6 +603,12 @@ public class MainWindow extends JFrame {
...
@@ -565,6 +603,12 @@ public class MainWindow extends JFrame {
tabbedPane
.
loadSettings
();
tabbedPane
.
loadSettings
();
}
}
@Override
public
void
dispose
()
{
cancelBackgroundJobs
();
super
.
dispose
();
}
public
JadxWrapper
getWrapper
()
{
public
JadxWrapper
getWrapper
()
{
return
wrapper
;
return
wrapper
;
}
}
...
@@ -581,6 +625,10 @@ public class MainWindow extends JFrame {
...
@@ -581,6 +625,10 @@ public class MainWindow extends JFrame {
return
cacheObject
;
return
cacheObject
;
}
}
public
BackgroundWorker
getBackgroundWorker
()
{
return
backgroundWorker
;
}
private
class
RecentFilesMenuListener
implements
MenuListener
{
private
class
RecentFilesMenuListener
implements
MenuListener
{
private
final
JMenu
recentFiles
;
private
final
JMenu
recentFiles
;
...
@@ -619,4 +667,5 @@ public class MainWindow extends JFrame {
...
@@ -619,4 +667,5 @@ public class MainWindow extends JFrame {
public
void
menuCanceled
(
MenuEvent
e
)
{
public
void
menuCanceled
(
MenuEvent
e
)
{
}
}
}
}
}
}
jadx-gui/src/main/java/jadx/gui/ui/ProgressPanel.java
0 → 100644
View file @
bc73010d
package
jadx
.
gui
.
ui
;
import
jadx.gui.utils.Utils
;
import
javax.swing.BorderFactory
;
import
javax.swing.BoxLayout
;
import
javax.swing.Icon
;
import
javax.swing.JButton
;
import
javax.swing.JLabel
;
import
javax.swing.JPanel
;
import
javax.swing.JProgressBar
;
import
javax.swing.SwingWorker
;
import
java.awt.Dimension
;
import
java.awt.event.ActionEvent
;
import
java.awt.event.ActionListener
;
import
java.beans.PropertyChangeEvent
;
import
java.beans.PropertyChangeListener
;
public
class
ProgressPanel
extends
JPanel
implements
PropertyChangeListener
{
private
static
final
long
serialVersionUID
=
-
3238438119672015733L
;
private
static
final
Icon
ICON_CANCEL
=
Utils
.
openIcon
(
"cross"
);
private
final
JProgressBar
progressBar
;
private
final
JLabel
progressLabel
;
public
ProgressPanel
(
final
MainWindow
mainWindow
,
boolean
showCancelButton
)
{
progressLabel
=
new
JLabel
();
progressBar
=
new
JProgressBar
(
0
,
100
);
progressBar
.
setIndeterminate
(
true
);
progressBar
.
setStringPainted
(
false
);
progressLabel
.
setLabelFor
(
progressBar
);
setBorder
(
BorderFactory
.
createEmptyBorder
(
2
,
2
,
2
,
2
));
setLayout
(
new
BoxLayout
(
this
,
BoxLayout
.
X_AXIS
));
setVisible
(
false
);
add
(
progressLabel
);
add
(
progressBar
);
if
(
showCancelButton
)
{
JButton
cancelButton
=
new
JButton
(
ICON_CANCEL
);
cancelButton
.
setPreferredSize
(
new
Dimension
(
ICON_CANCEL
.
getIconWidth
(),
ICON_CANCEL
.
getIconHeight
()));
cancelButton
.
setToolTipText
(
"Cancel background jobs"
);
cancelButton
.
setBorderPainted
(
false
);
cancelButton
.
setFocusPainted
(
false
);
cancelButton
.
setContentAreaFilled
(
false
);
cancelButton
.
addActionListener
(
new
ActionListener
()
{
@Override
public
void
actionPerformed
(
ActionEvent
e
)
{
mainWindow
.
cancelBackgroundJobs
();
}
});
add
(
cancelButton
);
}
}
@Override
public
void
propertyChange
(
PropertyChangeEvent
evt
)
{
if
(
"progress"
.
equals
(
evt
.
getPropertyName
()))
{
int
progress
=
(
Integer
)
evt
.
getNewValue
();
progressBar
.
setIndeterminate
(
false
);
progressBar
.
setValue
(
progress
);
progressBar
.
setString
(
progress
+
"%"
);
progressBar
.
setStringPainted
(
true
);
}
else
if
(
"label"
.
equals
(
evt
.
getPropertyName
()))
{
setLabel
((
String
)
evt
.
getNewValue
());
}
}
public
void
setLabel
(
String
label
)
{
progressLabel
.
setText
(
label
);
}
public
void
setIndeterminate
(
boolean
newValue
)
{
progressBar
.
setIndeterminate
(
newValue
);
}
public
void
changeLabel
(
SwingWorker
<?,
?>
task
,
String
label
)
{
task
.
firePropertyChange
(
"label"
,
null
,
label
);
}
}
jadx-gui/src/main/java/jadx/gui/ui/SearchDialog.java
View file @
bc73010d
package
jadx
.
gui
.
ui
;
package
jadx
.
gui
.
ui
;
import
jadx.api.JavaClass
;
import
jadx.gui.JadxWrapper
;
import
jadx.gui.treemodel.JNode
;
import
jadx.gui.treemodel.TextNode
;
import
jadx.gui.utils.CacheObject
;
import
jadx.gui.utils.NLS
;
import
jadx.gui.utils.NLS
;
import
jadx.gui.utils.Position
;
import
jadx.gui.utils.TextSearchIndex
;
import
jadx.gui.utils.TextSearchIndex
;
import
jadx.gui.utils.TextStandardActions
;
import
jadx.gui.utils.TextStandardActions
;
import
javax.swing.BorderFactory
;
import
javax.swing.BorderFactory
;
import
javax.swing.Box
;
import
javax.swing.Box
;
import
javax.swing.BoxLayout
;
import
javax.swing.BoxLayout
;
import
javax.swing.DefaultListModel
;
import
javax.swing.JButton
;
import
javax.swing.JCheckBox
;
import
javax.swing.JCheckBox
;
import
javax.swing.JComponent
;
import
javax.swing.JDialog
;
import
javax.swing.JLabel
;
import
javax.swing.JLabel
;
import
javax.swing.JList
;
import
javax.swing.JPanel
;
import
javax.swing.JPanel
;
import
javax.swing.JProgressBar
;
import
javax.swing.JScrollPane
;
import
javax.swing.JTextField
;
import
javax.swing.JTextField
;
import
javax.swing.KeyStroke
;
import
javax.swing.ListCellRenderer
;
import
javax.swing.SwingUtilities
;
import
javax.swing.SwingUtilities
;
import
javax.swing.SwingWorker
;
import
javax.swing.UIDefaults
;
import
javax.swing.UIManager
;
import
javax.swing.WindowConstants
;
import
javax.swing.WindowConstants
;
import
javax.swing.event.DocumentEvent
;
import
javax.swing.event.DocumentEvent
;
import
javax.swing.event.DocumentListener
;
import
javax.swing.event.DocumentListener
;
import
java.awt.BorderLayout
;
import
java.awt.BorderLayout
;
import
java.awt.Color
;
import
java.awt.Component
;
import
java.awt.Container
;
import
java.awt.Container
;
import
java.awt.Cursor
;
import
java.awt.Dimension
;
import
java.awt.Dimension
;
import
java.awt.FlowLayout
;
import
java.awt.FlowLayout
;
import
java.awt.event.ActionEvent
;
import
java.awt.event.ActionListener
;
import
java.awt.event.ItemEvent
;
import
java.awt.event.ItemEvent
;
import
java.awt.event.ItemListener
;
import
java.awt.event.ItemListener
;
import
java.awt.event.KeyAdapter
;
import
java.awt.event.KeyAdapter
;
import
java.awt.event.KeyEvent
;
import
java.awt.event.KeyEvent
;
import
java.awt.event.MouseAdapter
;
import
java.awt.event.MouseEvent
;
import
java.awt.event.WindowAdapter
;
import
java.awt.event.WindowAdapter
;
import
java.awt.event.WindowEvent
;
import
java.awt.event.WindowEvent
;
import
java.util.EnumSet
;
import
java.util.EnumSet
;
...
@@ -56,12 +31,11 @@ import java.util.Set;
...
@@ -56,12 +31,11 @@ import java.util.Set;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
public
class
SearchDialog
extends
J
Dialog
{
public
class
SearchDialog
extends
CommonSearch
Dialog
{
private
static
final
long
serialVersionUID
=
-
5105405456969134105L
;
private
static
final
long
serialVersionUID
=
-
5105405456969134105L
;
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
SearchDialog
.
class
);
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
SearchDialog
.
class
);
private
static
final
int
MAX_RESULTS_COUNT
=
500
;
enum
SearchOptions
{
enum
SearchOptions
{
CLASS
,
CLASS
,
...
@@ -72,67 +46,43 @@ public class SearchDialog extends JDialog {
...
@@ -72,67 +46,43 @@ public class SearchDialog extends JDialog {
private
Set
<
SearchOptions
>
options
=
EnumSet
.
allOf
(
SearchOptions
.
class
);
private
Set
<
SearchOptions
>
options
=
EnumSet
.
allOf
(
SearchOptions
.
class
);
private
final
TabbedPane
tabbedPane
;
private
final
JadxWrapper
wrapper
;
private
final
CacheObject
cache
;
private
JTextField
searchField
;
private
JTextField
searchField
;
private
ResultsModel
resultsModel
;
private
JList
resultsList
;
private
JProgressBar
busyBar
;
public
SearchDialog
(
MainWindow
mainWindow
,
Set
<
SearchOptions
>
options
)
{
public
SearchDialog
(
MainWindow
mainWindow
,
Set
<
SearchOptions
>
options
)
{
super
(
mainWindow
);
super
(
mainWindow
);
this
.
tabbedPane
=
mainWindow
.
getTabbedPane
();
this
.
wrapper
=
mainWindow
.
getWrapper
();
this
.
cache
=
mainWindow
.
getCacheObject
();
this
.
options
=
options
;
this
.
options
=
options
;
initUI
();
initUI
();
addWindowListener
(
new
WindowAdapter
()
{
addWindowListener
(
new
WindowAdapter
()
{
@Override
@Override
public
void
window
Activat
ed
(
WindowEvent
e
)
{
public
void
window
Open
ed
(
WindowEvent
e
)
{
SwingUtilities
.
invokeLater
(
new
Runnable
()
{
SwingUtilities
.
invokeLater
(
new
Runnable
()
{
@Override
@Override
public
void
run
()
{
public
void
run
()
{
prepare
();
openInit
();
searchField
.
requestFocus
();
}
}
});
});
}
}
});
});
}
}
public
void
prepare
()
{
protected
void
openInit
()
{
TextSearchIndex
index
=
cache
.
getTextIndex
();
prepare
();
if
(
index
!=
null
)
{
String
lastSearch
=
cache
.
getLastSearch
();
return
;
if
(
lastSearch
!=
null
)
{
searchField
.
setText
(
lastSearch
);
searchField
.
selectAll
();
}
}
LoadTask
task
=
new
LoadTask
();
searchField
.
requestFocus
();
task
.
execute
();
}
private
void
loadData
()
{
TextSearchIndex
index
=
cache
.
getTextIndex
();
if
(
index
!=
null
)
{
return
;
}
index
=
new
TextSearchIndex
();
for
(
JavaClass
cls
:
wrapper
.
getClasses
())
{
index
.
indexNames
(
cls
);
}
for
(
JavaClass
cls
:
wrapper
.
getClasses
())
{
index
.
indexCode
(
cls
);
}
cache
.
setTextIndex
(
index
);
}
}
private
synchronized
void
performSearch
()
{
private
synchronized
void
performSearch
()
{
resultsModel
.
removeAllElements
();
resultsModel
.
clear
();
String
text
=
searchField
.
getText
();
String
text
=
searchField
.
getText
();
if
(
text
==
null
||
text
.
isEmpty
()
||
options
.
isEmpty
())
{
if
(
text
==
null
||
text
.
isEmpty
()
||
options
.
isEmpty
())
{
return
;
return
;
}
}
cache
.
setLastSearch
(
text
);
TextSearchIndex
index
=
cache
.
getTextIndex
();
TextSearchIndex
index
=
cache
.
getTextIndex
();
if
(
index
==
null
)
{
if
(
index
==
null
)
{
return
;
return
;
...
@@ -149,92 +99,9 @@ public class SearchDialog extends JDialog {
...
@@ -149,92 +99,9 @@ public class SearchDialog extends JDialog {
if
(
options
.
contains
(
SearchOptions
.
CODE
))
{
if
(
options
.
contains
(
SearchOptions
.
CODE
))
{
resultsModel
.
addAll
(
index
.
searchCode
(
text
));
resultsModel
.
addAll
(
index
.
searchCode
(
text
));
}
}
LOG
.
info
(
"Search returned {} results"
,
resultsModel
.
size
());
highlightText
=
text
;
}
resultsTable
.
updateTable
();
private
void
openSelectedItem
()
{
int
selectedId
=
resultsList
.
getSelectedIndex
();
if
(
selectedId
==
-
1
)
{
return
;
}
JNode
node
=
(
JNode
)
resultsModel
.
get
(
selectedId
);
tabbedPane
.
showCode
(
new
Position
(
node
.
getRootClass
(),
node
.
getLine
()));
dispose
();
}
}
private
class
LoadTask
extends
SwingWorker
<
Void
,
Void
>
{
public
LoadTask
()
{
setCursor
(
Cursor
.
getPredefinedCursor
(
Cursor
.
WAIT_CURSOR
));
busyBar
.
setVisible
(
true
);
searchField
.
setEnabled
(
false
);
resultsList
.
setEnabled
(
false
);
}
@Override
public
Void
doInBackground
()
{
loadData
();
return
null
;
}
@Override
public
void
done
()
{
SwingUtilities
.
invokeLater
(
new
Runnable
()
{
public
void
run
()
{
setCursor
(
null
);
searchField
.
setEnabled
(
true
);
resultsList
.
setEnabled
(
true
);
busyBar
.
setVisible
(
false
);
}
});
}
}
private
static
class
ResultsModel
extends
DefaultListModel
{
private
static
final
long
serialVersionUID
=
-
7821286846923903208L
;
private
void
addAll
(
Iterable
<?
extends
JNode
>
nodes
)
{
for
(
JNode
node
:
nodes
)
{
if
(
size
()
>=
MAX_RESULTS_COUNT
)
{
if
(
size
()
==
MAX_RESULTS_COUNT
)
{
addElement
(
new
TextNode
(
"Search results truncated (limit: "
+
MAX_RESULTS_COUNT
+
")"
));
}
return
;
}
addElement
(
node
);
}
}
}
private
static
class
ResultsCellRenderer
implements
ListCellRenderer
{
private
final
Color
selectedBackground
;
private
final
Color
selectedForeground
;
ResultsCellRenderer
()
{
UIDefaults
defaults
=
UIManager
.
getDefaults
();
selectedBackground
=
defaults
.
getColor
(
"List.selectionBackground"
);
selectedForeground
=
defaults
.
getColor
(
"List.selectionForeground"
);
}
@Override
public
Component
getListCellRendererComponent
(
JList
list
,
Object
obj
,
int
index
,
boolean
isSelected
,
boolean
cellHasFocus
)
{
if
(!(
obj
instanceof
JNode
))
{
return
null
;
}
JNode
value
=
(
JNode
)
obj
;
JLabel
label
=
new
JLabel
();
label
.
setOpaque
(
true
);
label
.
setIcon
(
value
.
getIcon
());
label
.
setText
(
value
.
makeLongString
());
if
(
isSelected
)
{
label
.
setBackground
(
selectedBackground
);
label
.
setForeground
(
selectedForeground
);
}
return
label
;
}
}
private
class
SearchFieldListener
implements
DocumentListener
{
private
class
SearchFieldListener
implements
DocumentListener
{
public
void
changedUpdate
(
DocumentEvent
e
)
{
public
void
changedUpdate
(
DocumentEvent
e
)
{
...
@@ -263,17 +130,6 @@ public class SearchDialog extends JDialog {
...
@@ -263,17 +130,6 @@ public class SearchDialog extends JDialog {
JCheckBox
fldChBox
=
makeOptionsCheckBox
(
NLS
.
str
(
"search_dialog.field"
),
SearchOptions
.
FIELD
);
JCheckBox
fldChBox
=
makeOptionsCheckBox
(
NLS
.
str
(
"search_dialog.field"
),
SearchOptions
.
FIELD
);
JCheckBox
codeChBox
=
makeOptionsCheckBox
(
NLS
.
str
(
"search_dialog.code"
),
SearchOptions
.
CODE
);
JCheckBox
codeChBox
=
makeOptionsCheckBox
(
NLS
.
str
(
"search_dialog.code"
),
SearchOptions
.
CODE
);
resultsModel
=
new
ResultsModel
();
resultsList
=
new
JList
(
resultsModel
);
resultsList
.
setCellRenderer
(
new
ResultsCellRenderer
());
resultsList
.
addMouseListener
(
new
MouseAdapter
()
{
public
void
mouseClicked
(
MouseEvent
evt
)
{
if
(
evt
.
getClickCount
()
==
2
)
{
openSelectedItem
();
}
}
});
JPanel
searchOptions
=
new
JPanel
(
new
FlowLayout
(
FlowLayout
.
LEFT
));
JPanel
searchOptions
=
new
JPanel
(
new
FlowLayout
(
FlowLayout
.
LEFT
));
searchOptions
.
setBorder
(
BorderFactory
.
createTitledBorder
(
NLS
.
str
(
"search_dialog.search_in"
)));
searchOptions
.
setBorder
(
BorderFactory
.
createTitledBorder
(
NLS
.
str
(
"search_dialog.search_in"
)));
searchOptions
.
add
(
clsChBox
);
searchOptions
.
add
(
clsChBox
);
...
@@ -292,68 +148,30 @@ public class SearchDialog extends JDialog {
...
@@ -292,68 +148,30 @@ public class SearchDialog extends JDialog {
searchPane
.
add
(
searchOptions
);
searchPane
.
add
(
searchOptions
);
searchPane
.
setBorder
(
BorderFactory
.
createEmptyBorder
(
10
,
10
,
10
,
10
));
searchPane
.
setBorder
(
BorderFactory
.
createEmptyBorder
(
10
,
10
,
10
,
10
));
JPanel
listPane
=
new
JPanel
();
initCommon
();
listPane
.
setLayout
(
new
BoxLayout
(
listPane
,
BoxLayout
.
PAGE_AXIS
));
JPanel
resultsPanel
=
initResultsTable
();
listPane
.
add
(
new
JScrollPane
(
resultsList
));
JPanel
buttonPane
=
initButtonsPanel
();
listPane
.
setBorder
(
BorderFactory
.
createEmptyBorder
(
0
,
10
,
10
,
10
));
busyBar
=
new
JProgressBar
();
busyBar
.
setIndeterminate
(
true
);
busyBar
.
setVisible
(
false
);
//Create and initialize the buttons.
JButton
cancelButton
=
new
JButton
(
NLS
.
str
(
"search_dialog.cancel"
));
cancelButton
.
addActionListener
(
new
ActionListener
()
{
public
void
actionPerformed
(
ActionEvent
event
)
{
dispose
();
}
});
JButton
openBtn
=
new
JButton
(
NLS
.
str
(
"search_dialog.open"
));
openBtn
.
addActionListener
(
new
ActionListener
()
{
public
void
actionPerformed
(
ActionEvent
event
)
{
openSelectedItem
();
}
});
JPanel
buttonPane
=
new
JPanel
();
buttonPane
.
setLayout
(
new
BoxLayout
(
buttonPane
,
BoxLayout
.
LINE_AXIS
));
buttonPane
.
setBorder
(
BorderFactory
.
createEmptyBorder
(
0
,
10
,
10
,
10
));
buttonPane
.
add
(
busyBar
);
buttonPane
.
add
(
Box
.
createRigidArea
(
new
Dimension
(
5
,
0
)));
buttonPane
.
add
(
Box
.
createHorizontalGlue
());
buttonPane
.
add
(
openBtn
);
buttonPane
.
add
(
Box
.
createRigidArea
(
new
Dimension
(
10
,
0
)));
buttonPane
.
add
(
cancelButton
);
Container
contentPane
=
getContentPane
();
Container
contentPane
=
getContentPane
();
contentPane
.
add
(
searchPane
,
BorderLayout
.
PAGE_START
);
contentPane
.
add
(
searchPane
,
BorderLayout
.
PAGE_START
);
contentPane
.
add
(
listPane
,
BorderLayout
.
CENTER
);
contentPane
.
add
(
resultsPanel
,
BorderLayout
.
CENTER
);
contentPane
.
add
(
buttonPane
,
BorderLayout
.
PAGE_END
);
contentPane
.
add
(
buttonPane
,
BorderLayout
.
PAGE_END
);
getRootPane
().
setDefaultButton
(
openBtn
);
searchField
.
addKeyListener
(
new
KeyAdapter
()
{
searchField
.
addKeyListener
(
new
KeyAdapter
()
{
@Override
@Override
public
void
keyReleased
(
KeyEvent
e
)
{
public
void
keyReleased
(
KeyEvent
e
)
{
if
(
e
.
getKeyCode
()
==
KeyEvent
.
VK_ENTER
)
{
if
(
e
.
getKeyCode
()
==
KeyEvent
.
VK_ENTER
)
{
resultsList
.
requestFocus
();
if
(
resultsModel
.
getRowCount
()
!=
0
)
{
if
(!
resultsModel
.
isEmpty
())
{
resultsTable
.
setRowSelectionInterval
(
0
,
0
);
resultsList
.
setSelectedIndex
(
0
);
}
}
resultsTable
.
requestFocus
();
}
}
}
}
});
});
KeyStroke
stroke
=
KeyStroke
.
getKeyStroke
(
KeyEvent
.
VK_ESCAPE
,
0
);
getRootPane
().
registerKeyboardAction
(
new
ActionListener
()
{
@Override
public
void
actionPerformed
(
ActionEvent
e
)
{
dispose
();
}
},
stroke
,
JComponent
.
WHEN_IN_FOCUSED_WINDOW
);
setTitle
(
NLS
.
str
(
"menu.text_search"
));
setTitle
(
NLS
.
str
(
"menu.text_search"
));
pack
();
pack
();
setSize
(
7
00
,
500
);
setSize
(
8
00
,
500
);
setLocationRelativeTo
(
null
);
setLocationRelativeTo
(
null
);
setDefaultCloseOperation
(
WindowConstants
.
DISPOSE_ON_CLOSE
);
setDefaultCloseOperation
(
WindowConstants
.
DISPOSE_ON_CLOSE
);
setModalityType
(
ModalityType
.
MODELESS
);
setModalityType
(
ModalityType
.
MODELESS
);
...
@@ -375,4 +193,14 @@ public class SearchDialog extends JDialog {
...
@@ -375,4 +193,14 @@ public class SearchDialog extends JDialog {
});
});
return
chBox
;
return
chBox
;
}
}
@Override
protected
void
loadFinished
()
{
searchField
.
setEnabled
(
true
);
}
@Override
protected
void
loadStart
()
{
searchField
.
setEnabled
(
false
);
}
}
}
jadx-gui/src/main/java/jadx/gui/ui/TabbedPane.java
View file @
bc73010d
...
@@ -16,6 +16,7 @@ import javax.swing.JPopupMenu;
...
@@ -16,6 +16,7 @@ import javax.swing.JPopupMenu;
import
javax.swing.JTabbedPane
;
import
javax.swing.JTabbedPane
;
import
javax.swing.SwingUtilities
;
import
javax.swing.SwingUtilities
;
import
javax.swing.plaf.basic.BasicButtonUI
;
import
javax.swing.plaf.basic.BasicButtonUI
;
import
javax.swing.text.BadLocationException
;
import
java.awt.Component
;
import
java.awt.Component
;
import
java.awt.FlowLayout
;
import
java.awt.FlowLayout
;
import
java.awt.event.ActionEvent
;
import
java.awt.event.ActionEvent
;
...
@@ -29,8 +30,13 @@ import java.util.LinkedHashMap;
...
@@ -29,8 +30,13 @@ import java.util.LinkedHashMap;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Map
;
import
org.jetbrains.annotations.Nullable
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
class
TabbedPane
extends
JTabbedPane
{
class
TabbedPane
extends
JTabbedPane
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
TabbedPane
.
class
);
private
static
final
long
serialVersionUID
=
-
8833600618794570904L
;
private
static
final
long
serialVersionUID
=
-
8833600618794570904L
;
private
static
final
ImageIcon
ICON_CLOSE
=
Utils
.
openIcon
(
"cross"
);
private
static
final
ImageIcon
ICON_CLOSE
=
Utils
.
openIcon
(
"cross"
);
...
@@ -65,19 +71,46 @@ class TabbedPane extends JTabbedPane {
...
@@ -65,19 +71,46 @@ class TabbedPane extends JTabbedPane {
return
mainWindow
;
return
mainWindow
;
}
}
void
showCode
(
final
Position
pos
)
{
private
void
showCode
(
final
Position
pos
)
{
final
ContentPanel
contentPanel
=
getCodePanel
(
pos
.
getNode
());
final
ContentPanel
contentPanel
=
getCodePanel
(
pos
.
getNode
());
SwingUtilities
.
invokeLater
(
new
Runnable
()
{
SwingUtilities
.
invokeLater
(
new
Runnable
()
{
@Override
@Override
public
void
run
()
{
public
void
run
()
{
setSelectedComponent
(
contentPanel
);
setSelectedComponent
(
contentPanel
);
ContentArea
contentArea
=
contentPanel
.
getContentArea
();
ContentArea
contentArea
=
contentPanel
.
getContentArea
();
contentArea
.
scrollToLine
(
pos
.
getLine
());
int
line
=
pos
.
getLine
();
if
(
line
<
0
)
{
try
{
line
=
1
+
contentArea
.
getLineOfOffset
(-
line
);
}
catch
(
BadLocationException
e
)
{
LOG
.
error
(
"Can't get line for: {}"
,
pos
,
e
);
line
=
pos
.
getNode
().
getLine
();
}
}
contentArea
.
scrollToLine
(
line
);
contentArea
.
requestFocus
();
contentArea
.
requestFocus
();
}
}
});
});
}
}
public
void
codeJump
(
Position
pos
)
{
Position
curPos
=
getCurrentPosition
();
if
(
curPos
!=
null
)
{
jumps
.
addPosition
(
curPos
);
jumps
.
addPosition
(
pos
);
}
showCode
(
pos
);
}
@Nullable
private
Position
getCurrentPosition
()
{
ContentPanel
selectedCodePanel
=
getSelectedCodePanel
();
if
(
selectedCodePanel
==
null
)
{
return
null
;
}
return
selectedCodePanel
.
getContentArea
().
getCurrentPosition
();
}
public
void
navBack
()
{
public
void
navBack
()
{
Position
pos
=
jumps
.
getPrev
();
Position
pos
=
jumps
.
getPrev
();
if
(
pos
!=
null
)
{
if
(
pos
!=
null
)
{
...
@@ -116,6 +149,7 @@ class TabbedPane extends JTabbedPane {
...
@@ -116,6 +149,7 @@ class TabbedPane extends JTabbedPane {
return
panel
;
return
panel
;
}
}
@Nullable
ContentPanel
getSelectedCodePanel
()
{
ContentPanel
getSelectedCodePanel
()
{
return
(
ContentPanel
)
getSelectedComponent
();
return
(
ContentPanel
)
getSelectedComponent
();
}
}
...
...
jadx-gui/src/main/java/jadx/gui/ui/UsageDialog.java
0 → 100644
View file @
bc73010d
package
jadx
.
gui
.
ui
;
import
jadx.gui.treemodel.JNode
;
import
jadx.gui.utils.CodeUsageInfo
;
import
jadx.gui.utils.NLS
;
import
javax.swing.BorderFactory
;
import
javax.swing.JLabel
;
import
javax.swing.JPanel
;
import
javax.swing.SwingConstants
;
import
javax.swing.SwingUtilities
;
import
javax.swing.WindowConstants
;
import
java.awt.BorderLayout
;
import
java.awt.Container
;
import
java.awt.FlowLayout
;
import
java.awt.event.WindowAdapter
;
import
java.awt.event.WindowEvent
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
public
class
UsageDialog
extends
CommonSearchDialog
{
private
static
final
long
serialVersionUID
=
-
5105405789969134105L
;
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
UsageDialog
.
class
);
private
final
JNode
node
;
public
UsageDialog
(
MainWindow
mainWindow
,
JNode
node
)
{
super
(
mainWindow
);
this
.
node
=
node
;
initUI
();
addWindowListener
(
new
WindowAdapter
()
{
@Override
public
void
windowOpened
(
WindowEvent
e
)
{
SwingUtilities
.
invokeLater
(
new
Runnable
()
{
@Override
public
void
run
()
{
openInit
();
}
});
}
});
}
protected
void
openInit
()
{
prepare
();
}
@Override
protected
void
loadFinished
()
{
performSearch
();
}
@Override
protected
void
loadStart
()
{
}
private
synchronized
void
performSearch
()
{
resultsModel
.
clear
();
CodeUsageInfo
usageInfo
=
cache
.
getUsageInfo
();
if
(
usageInfo
==
null
)
{
return
;
}
resultsModel
.
addAll
(
usageInfo
.
getUsageList
(
node
));
// TODO: highlight only needed node usage
highlightText
=
null
;
resultsTable
.
updateTable
();
}
private
void
initUI
()
{
JLabel
lbl
=
new
JLabel
(
NLS
.
str
(
"usage_dialog.label"
));
JLabel
nodeLabel
=
new
JLabel
(
this
.
node
.
makeLongString
(),
this
.
node
.
getIcon
(),
SwingConstants
.
LEFT
);
lbl
.
setLabelFor
(
nodeLabel
);
JPanel
searchPane
=
new
JPanel
();
searchPane
.
setLayout
(
new
FlowLayout
(
FlowLayout
.
LEFT
));
searchPane
.
add
(
lbl
);
searchPane
.
add
(
nodeLabel
);
searchPane
.
setBorder
(
BorderFactory
.
createEmptyBorder
(
10
,
10
,
10
,
10
));
initCommon
();
JPanel
resultsPanel
=
initResultsTable
();
JPanel
buttonPane
=
initButtonsPanel
();
Container
contentPane
=
getContentPane
();
contentPane
.
add
(
searchPane
,
BorderLayout
.
PAGE_START
);
contentPane
.
add
(
resultsPanel
,
BorderLayout
.
CENTER
);
contentPane
.
add
(
buttonPane
,
BorderLayout
.
PAGE_END
);
setTitle
(
NLS
.
str
(
"usage_dialog.title"
));
pack
();
setSize
(
800
,
500
);
setLocationRelativeTo
(
null
);
setDefaultCloseOperation
(
WindowConstants
.
DISPOSE_ON_CLOSE
);
setModalityType
(
ModalityType
.
MODELESS
);
}
}
jadx-gui/src/main/java/jadx/gui/utils/CacheObject.java
View file @
bc73010d
package
jadx
.
gui
.
utils
;
package
jadx
.
gui
.
utils
;
import
jadx.gui.jobs.DecompileJob
;
import
jadx.gui.jobs.IndexJob
;
import
org.jetbrains.annotations.Nullable
;
import
org.jetbrains.annotations.Nullable
;
public
class
CacheObject
{
public
class
CacheObject
{
@Nullable
private
DecompileJob
decompileJob
;
private
IndexJob
indexJob
;
private
TextSearchIndex
textIndex
;
private
TextSearchIndex
textIndex
;
private
CodeUsageInfo
usageInfo
;
private
String
lastSearch
;
public
void
reset
()
{
public
void
reset
()
{
textIndex
=
null
;
textIndex
=
null
;
lastSearch
=
null
;
usageInfo
=
null
;
}
public
DecompileJob
getDecompileJob
()
{
return
decompileJob
;
}
public
void
setDecompileJob
(
DecompileJob
decompileJob
)
{
this
.
decompileJob
=
decompileJob
;
}
}
@Nullable
@Nullable
...
@@ -15,7 +33,33 @@ public class CacheObject {
...
@@ -15,7 +33,33 @@ public class CacheObject {
return
textIndex
;
return
textIndex
;
}
}
public
void
setTextIndex
(
@Nullable
TextSearchIndex
textIndex
)
{
public
void
setTextIndex
(
TextSearchIndex
textIndex
)
{
this
.
textIndex
=
textIndex
;
this
.
textIndex
=
textIndex
;
}
}
@Nullable
public
String
getLastSearch
()
{
return
lastSearch
;
}
public
void
setLastSearch
(
String
lastSearch
)
{
this
.
lastSearch
=
lastSearch
;
}
@Nullable
public
CodeUsageInfo
getUsageInfo
()
{
return
usageInfo
;
}
public
void
setUsageInfo
(
@Nullable
CodeUsageInfo
usageInfo
)
{
this
.
usageInfo
=
usageInfo
;
}
public
IndexJob
getIndexJob
()
{
return
indexJob
;
}
public
void
setIndexJob
(
IndexJob
indexJob
)
{
this
.
indexJob
=
indexJob
;
}
}
}
jadx-gui/src/main/java/jadx/gui/utils/CodeLinesInfo.java
0 → 100644
View file @
bc73010d
package
jadx
.
gui
.
utils
;
import
jadx.api.JavaClass
;
import
jadx.api.JavaMethod
;
import
jadx.api.JavaNode
;
import
java.util.Map
;
import
java.util.NavigableMap
;
import
java.util.TreeMap
;
public
class
CodeLinesInfo
{
private
NavigableMap
<
Integer
,
JavaNode
>
map
=
new
TreeMap
<
Integer
,
JavaNode
>();
public
CodeLinesInfo
(
JavaClass
cls
)
{
addClass
(
cls
);
}
public
void
addClass
(
JavaClass
cls
)
{
map
.
put
(
cls
.
getDecompiledLine
(),
cls
);
for
(
JavaClass
innerCls
:
cls
.
getInnerClasses
())
{
map
.
put
(
innerCls
.
getDecompiledLine
(),
innerCls
);
addClass
(
innerCls
);
}
for
(
JavaMethod
mth
:
cls
.
getMethods
())
{
map
.
put
(
mth
.
getDecompiledLine
(),
mth
);
}
}
public
JavaNode
getJavaNodeByLine
(
int
line
)
{
Map
.
Entry
<
Integer
,
JavaNode
>
entry
=
map
.
floorEntry
(
line
);
if
(
entry
==
null
)
{
return
null
;
}
return
entry
.
getValue
();
}
}
jadx-gui/src/main/java/jadx/gui/utils/CodeUsageInfo.java
0 → 100644
View file @
bc73010d
package
jadx
.
gui
.
utils
;
import
jadx.api.CodePosition
;
import
jadx.api.JavaClass
;
import
jadx.api.JavaNode
;
import
jadx.gui.treemodel.CodeNode
;
import
jadx.gui.treemodel.JNode
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
public
class
CodeUsageInfo
{
public
static
class
UsageInfo
{
private
final
List
<
CodeNode
>
usageList
=
new
ArrayList
<
CodeNode
>();
public
List
<
CodeNode
>
getUsageList
()
{
return
usageList
;
}
}
private
final
Map
<
JNode
,
UsageInfo
>
usageMap
=
new
HashMap
<
JNode
,
UsageInfo
>();
public
void
processClass
(
JavaClass
javaClass
,
CodeLinesInfo
linesInfo
,
String
[]
lines
)
{
Map
<
CodePosition
,
JavaNode
>
usage
=
javaClass
.
getUsageMap
();
for
(
Map
.
Entry
<
CodePosition
,
JavaNode
>
entry
:
usage
.
entrySet
())
{
CodePosition
codePosition
=
entry
.
getKey
();
JavaNode
javaNode
=
entry
.
getValue
();
addUsage
(
JNode
.
makeFrom
(
javaNode
),
javaClass
,
linesInfo
,
codePosition
,
lines
);
}
}
private
void
addUsage
(
JNode
jNode
,
JavaClass
javaClass
,
CodeLinesInfo
linesInfo
,
CodePosition
codePosition
,
String
[]
lines
)
{
UsageInfo
usageInfo
=
usageMap
.
get
(
jNode
);
if
(
usageInfo
==
null
)
{
usageInfo
=
new
UsageInfo
();
usageMap
.
put
(
jNode
,
usageInfo
);
}
int
line
=
codePosition
.
getLine
();
JavaNode
javaNodeByLine
=
linesInfo
.
getJavaNodeByLine
(
line
);
String
codeLine
=
lines
[
line
-
1
].
trim
();
CodeNode
codeNode
=
new
CodeNode
(
javaNodeByLine
==
null
?
javaClass
:
javaNodeByLine
,
line
,
codeLine
);
usageInfo
.
getUsageList
().
add
(
codeNode
);
}
public
List
<
CodeNode
>
getUsageList
(
JNode
node
)
{
UsageInfo
usageInfo
=
usageMap
.
get
(
node
);
if
(
usageInfo
==
null
)
{
return
Collections
.
emptyList
();
}
return
usageInfo
.
getUsageList
();
}
}
jadx-gui/src/main/java/jadx/gui/utils/LogCollector.java
View file @
bc73010d
...
@@ -49,7 +49,7 @@ public class LogCollector extends CyclicBufferAppender<ILoggingEvent> {
...
@@ -49,7 +49,7 @@ public class LogCollector extends CyclicBufferAppender<ILoggingEvent> {
public
LogCollector
()
{
public
LogCollector
()
{
setName
(
"LogCollector"
);
setName
(
"LogCollector"
);
setMaxSize
(
5000
0
);
setMaxSize
(
5000
);
}
}
@Override
@Override
...
...
jadx-gui/src/main/java/jadx/gui/utils/SuffixTree.java
0 → 100644
View file @
bc73010d
package
jadx
.
gui
.
utils
;
import
com.googlecode.concurrenttrees.radix.node.concrete.DefaultCharArrayNodeFactory
;
import
com.googlecode.concurrenttrees.suffix.ConcurrentSuffixTree
;
public
class
SuffixTree
<
V
>
{
private
final
ConcurrentSuffixTree
<
V
>
tree
;
public
SuffixTree
()
{
this
.
tree
=
new
ConcurrentSuffixTree
<
V
>(
new
DefaultCharArrayNodeFactory
());
}
public
void
put
(
String
str
,
V
value
)
{
if
(
str
==
null
||
str
.
isEmpty
())
{
return
;
}
tree
.
putIfAbsent
(
str
,
value
);
}
public
Iterable
<
V
>
getValuesForKeysContaining
(
String
str
)
{
return
tree
.
getValuesForKeysContaining
(
str
);
}
public
int
size
()
{
return
tree
.
size
();
}
}
jadx-gui/src/main/java/jadx/gui/utils/TextSearchIndex.java
View file @
bc73010d
...
@@ -3,19 +3,18 @@ package jadx.gui.utils;
...
@@ -3,19 +3,18 @@ package jadx.gui.utils;
import
jadx.api.JavaClass
;
import
jadx.api.JavaClass
;
import
jadx.api.JavaField
;
import
jadx.api.JavaField
;
import
jadx.api.JavaMethod
;
import
jadx.api.JavaMethod
;
import
jadx.api.JavaNode
;
import
jadx.core.codegen.CodeWriter
;
import
jadx.gui.treemodel.CodeNode
;
import
jadx.gui.treemodel.CodeNode
;
import
jadx.gui.treemodel.JNode
;
import
jadx.gui.treemodel.JNode
;
import
jadx.gui.ui.CommonSearchDialog
;
import
java.
io.BufferedReader
;
import
java.
util.ArrayList
;
import
java.
io.StringReader
;
import
java.
util.List
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
import
com.googlecode.concurrenttrees.radix.node.concrete.DefaultCharArrayNodeFactory
;
import
com.googlecode.concurrenttrees.suffix.ConcurrentSuffixTree
;
import
com.googlecode.concurrenttrees.suffix.SuffixTree
;
public
class
TextSearchIndex
{
public
class
TextSearchIndex
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
TextSearchIndex
.
class
);
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
TextSearchIndex
.
class
);
...
@@ -25,15 +24,16 @@ public class TextSearchIndex {
...
@@ -25,15 +24,16 @@ public class TextSearchIndex {
private
SuffixTree
<
JNode
>
fldNamesTree
;
private
SuffixTree
<
JNode
>
fldNamesTree
;
private
SuffixTree
<
CodeNode
>
codeTree
;
private
SuffixTree
<
CodeNode
>
codeTree
;
private
List
<
JavaClass
>
skippedClasses
=
new
ArrayList
<
JavaClass
>();
public
TextSearchIndex
()
{
public
TextSearchIndex
()
{
clsNamesTree
=
new
ConcurrentSuffixTree
<
JNode
>(
new
DefaultCharArrayNodeFactory
()
);
clsNamesTree
=
new
SuffixTree
<
JNode
>(
);
mthNamesTree
=
new
ConcurrentSuffixTree
<
JNode
>(
new
DefaultCharArrayNodeFactory
()
);
mthNamesTree
=
new
SuffixTree
<
JNode
>(
);
fldNamesTree
=
new
ConcurrentSuffixTree
<
JNode
>(
new
DefaultCharArrayNodeFactory
()
);
fldNamesTree
=
new
SuffixTree
<
JNode
>(
);
codeTree
=
new
ConcurrentSuffixTree
<
CodeNode
>(
new
DefaultCharArrayNodeFactory
()
);
codeTree
=
new
SuffixTree
<
CodeNode
>(
);
}
}
public
void
indexNames
(
JavaClass
cls
)
{
public
void
indexNames
(
JavaClass
cls
)
{
cls
.
decompile
();
clsNamesTree
.
put
(
cls
.
getFullName
(),
JNode
.
makeFrom
(
cls
));
clsNamesTree
.
put
(
cls
.
getFullName
(),
JNode
.
makeFrom
(
cls
));
for
(
JavaMethod
mth
:
cls
.
getMethods
())
{
for
(
JavaMethod
mth
:
cls
.
getMethods
())
{
mthNamesTree
.
put
(
mth
.
getFullName
(),
JNode
.
makeFrom
(
mth
));
mthNamesTree
.
put
(
mth
.
getFullName
(),
JNode
.
makeFrom
(
mth
));
...
@@ -46,18 +46,15 @@ public class TextSearchIndex {
...
@@ -46,18 +46,15 @@ public class TextSearchIndex {
}
}
}
}
public
void
indexCode
(
JavaClass
cls
)
{
public
void
indexCode
(
JavaClass
cls
,
CodeLinesInfo
linesInfo
,
String
[]
lines
)
{
try
{
try
{
String
code
=
cls
.
getCode
();
int
count
=
lines
.
length
;
BufferedReader
bufReader
=
new
BufferedReader
(
new
StringReader
(
code
));
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
String
line
;
String
line
=
lines
[
i
];
int
lineNum
=
0
;
while
((
line
=
bufReader
.
readLine
())
!=
null
)
{
lineNum
++;
line
=
line
.
trim
();
if
(!
line
.
isEmpty
())
{
if
(!
line
.
isEmpty
())
{
CodeNode
node
=
new
CodeNode
(
cls
,
lineNum
,
line
);
int
lineNum
=
i
+
1
;
codeTree
.
put
(
line
,
node
);
JavaNode
node
=
linesInfo
.
getJavaNodeByLine
(
lineNum
);
codeTree
.
put
(
line
,
new
CodeNode
(
node
==
null
?
cls
:
node
,
lineNum
,
line
));
}
}
}
}
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
...
@@ -78,6 +75,59 @@ public class TextSearchIndex {
...
@@ -78,6 +75,59 @@ public class TextSearchIndex {
}
}
public
Iterable
<
CodeNode
>
searchCode
(
String
text
)
{
public
Iterable
<
CodeNode
>
searchCode
(
String
text
)
{
return
codeTree
.
getValuesForKeysContaining
(
text
);
Iterable
<
CodeNode
>
items
;
if
(
codeTree
.
size
()
>
0
)
{
items
=
codeTree
.
getValuesForKeysContaining
(
text
);
if
(
skippedClasses
.
isEmpty
())
{
return
items
;
}
}
else
{
items
=
null
;
}
List
<
CodeNode
>
list
=
new
ArrayList
<
CodeNode
>();
if
(
items
!=
null
)
{
for
(
CodeNode
item
:
items
)
{
list
.
add
(
item
);
}
}
addSkippedClasses
(
list
,
text
);
return
list
;
}
private
void
addSkippedClasses
(
List
<
CodeNode
>
list
,
String
text
)
{
for
(
JavaClass
javaClass
:
skippedClasses
)
{
String
code
=
javaClass
.
getCode
();
int
pos
=
0
;
while
(
pos
!=
-
1
)
{
pos
=
searchNext
(
list
,
text
,
javaClass
,
code
,
pos
);
}
if
(
list
.
size
()
>
CommonSearchDialog
.
MAX_RESULTS_COUNT
)
{
return
;
}
}
}
private
int
searchNext
(
List
<
CodeNode
>
list
,
String
text
,
JavaNode
javaClass
,
String
code
,
int
startPos
)
{
int
pos
=
code
.
indexOf
(
text
,
startPos
);
if
(
pos
==
-
1
)
{
return
-
1
;
}
int
lineStart
=
1
+
code
.
lastIndexOf
(
CodeWriter
.
NL
,
pos
);
int
lineEnd
=
code
.
indexOf
(
CodeWriter
.
NL
,
pos
+
text
.
length
());
String
line
=
code
.
substring
(
lineStart
,
lineEnd
==
-
1
?
code
.
length
()
:
lineEnd
);
list
.
add
(
new
CodeNode
(
javaClass
,
-
pos
,
line
.
trim
()));
return
lineEnd
;
}
public
void
classCodeIndexSkipped
(
JavaClass
cls
)
{
this
.
skippedClasses
.
add
(
cls
);
}
public
List
<
JavaClass
>
getSkippedClasses
()
{
return
skippedClasses
;
}
public
int
getSkippedCount
()
{
return
skippedClasses
.
size
();
}
}
}
}
jadx-gui/src/main/java/jadx/gui/utils/Utils.java
View file @
bc73010d
...
@@ -84,4 +84,30 @@ public class Utils {
...
@@ -84,4 +84,30 @@ public class Utils {
}
}
return
overIcon
;
return
overIcon
;
}
}
public
static
boolean
isFreeMemoryAvailable
()
{
Runtime
runtime
=
Runtime
.
getRuntime
();
long
maxMemory
=
runtime
.
maxMemory
();
long
totalFree
=
runtime
.
freeMemory
()
+
maxMemory
-
runtime
.
totalMemory
();
return
totalFree
>
maxMemory
*
0.2
;
}
public
static
String
memoryInfo
()
{
Runtime
runtime
=
Runtime
.
getRuntime
();
StringBuilder
sb
=
new
StringBuilder
();
long
maxMemory
=
runtime
.
maxMemory
();
long
allocatedMemory
=
runtime
.
totalMemory
();
long
freeMemory
=
runtime
.
freeMemory
();
sb
.
append
(
"free: "
).
append
(
format
(
freeMemory
));
sb
.
append
(
", allocated: "
).
append
(
format
(
allocatedMemory
));
sb
.
append
(
", max: "
).
append
(
format
(
maxMemory
));
sb
.
append
(
", total free: "
).
append
(
format
(
freeMemory
+
maxMemory
-
allocatedMemory
));
return
sb
.
toString
();
}
private
static
String
format
(
long
mem
)
{
return
Long
.
toString
((
long
)
(
mem
/
1024
.
/
1024
.))
+
"MB"
;
}
}
}
jadx-gui/src/main/resources/i18n/Messages_en_US.properties
View file @
bc73010d
...
@@ -47,6 +47,9 @@ search_dialog.method=Method
...
@@ -47,6 +47,9 @@ search_dialog.method=Method
search_dialog.field
=
Field
search_dialog.field
=
Field
search_dialog.code
=
Code
search_dialog.code
=
Code
usage_dialog.title
=
Usage search
usage_dialog.label
=
Usage for:
preferences.title
=
Preferences
preferences.title
=
Preferences
preferences.deobfuscation
=
Deobfuscation
preferences.deobfuscation
=
Deobfuscation
preferences.other
=
Other
preferences.other
=
Other
...
@@ -58,6 +61,7 @@ preferences.threads=Processing threads count
...
@@ -58,6 +61,7 @@ preferences.threads=Processing threads count
preferences.cfg
=
Generate methods CFG graphs (in 'dot' format)
preferences.cfg
=
Generate methods CFG graphs (in 'dot' format)
preferences.raw_cfg
=
Generate RAW CFG graphs
preferences.raw_cfg
=
Generate RAW CFG graphs
preferences.font
=
Editor font
preferences.font
=
Editor font
preferences.fast_search
=
Fast search (uses more memory)
preferences.select_font
=
Select
preferences.select_font
=
Select
preferences.deobfuscation_on
=
Enable deobfuscation
preferences.deobfuscation_on
=
Enable deobfuscation
preferences.deobfuscation_force
=
Force rewrite deobfuscation map file
preferences.deobfuscation_force
=
Force rewrite deobfuscation map file
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment