I'm just learning Eclipse plugin development, currently for the purpose of adding a few simple custom commands that nobody else has bothered to implement. I've noticed that the Eclipse plugin API... leaves a lot to be desired. Are there any open source libraries which attempt to improve the plug-in development experience? (I've started to idly speculate about writing my own...).
I know Eclipse 4.0 is supposed to fix some of these issues long-term, but I'm unlikely to be able to move to it at work any time soon.
Edit
Here's an example of what I mean. This is an implementation of "hungry delete" functionality for emacs:
(defmacro hungry-delete-backward (&optional limit)
(if limit
`(let ((limit (or ,limit (point-min))))
(while (progn
;; skip-syntax-* doesn't count \n as whitespace..
(skip-chars-backward " \t\n\r\f\v" limit)
(and (eolp)
(eq (char-before) ?\\)
(> (point) limit)))
(backward-char)))
'(while (progn
(skip-chars-backward " \t\n\r\f\v")
(and (eolp)
(eq (char-before) ?\\)))
(backward-char))))
And here is part of an equivalent implementation for Eclipse, not including the manifest file, plugin.xml, or the Activator for the plugin:
#Override
public Object execute(ExecutionEvent event) throws ExecutionException {
IEditorPart editor = HandlerUtil.getActiveEditorChecked(event);
if (!(editor instanceof ITextEditor)) return null;
ITextEditor ite = (ITextEditor) editor;
IDocumentProvider idp = ite.getDocumentProvider();
IDocument doc = idp.getDocument(ite.getEditorInput());
ISelection selection = ite.getSelectionProvider().getSelection();
if (!(editor instanceof ITextSelection)) return null;
ITextSelection its = (ITextSelection) selection;
int currentCursorPosition = its.getOffset();
int deletionStart, deletionEnd;
if (its.getLength() == 0) {
deletionStart = currentCursorPosition - 1;
deletionEnd = currentCursorPosition;
FindReplaceDocumentAdapter frda = new FindReplaceDocumentAdapter(doc);
while (Character.isWhitespace(frda.charAt(deletionStart)) && deletionStart > 0) {
deletionStart--;
}
if (deletionStart != 0 && deletionStart + 1 != deletionEnd) deletionStart++;
} else {
deletionStart = its.getOffset();
deletionEnd = its.getOffset() + its.getLength();
}
int deletionLength = deletionEnd - deletionStart;
try {
doc.replace(deletionStart, deletionLength, "");
} catch (BadLocationException ble) {
// Bad location, just ignore it.
}
return null;
}
The chunk of boilerplate at the top of the Java version, for example, could be easily replaced by a library.
I think you're looking for something like Groovy-Monkey or Eclipse-Monkey, which allow you to do scripting to plug into Eclipse. I don't know much about either project, nor do I know if they are actively maintained (actually I know that Eclipse-Monkey is no longer maintained). But, these allow you to do emacs-like scripting inside of Eclipse.
Related
I am trying to read chapters from mp4 video files. I don't see this in the File.Tags list, but I was hoping there was a way to get them via requesting the chap atom.
I did try mp4chap, but it only gets me the first chapter. I think it may be meant for audio files only.
I am the author of mp4chap lib.
Yes, you are correct. mp4chap library is meant to use for audio files only.
Library is open source and really simple, you are free to modify it.
Here library analyze only first track (see code below). You can play with this code and get more data from mp4 tracks.
http://mp4chap.codeplex.com/SourceControl/latest#Mp4Chapters/ChapterExtractor.cs
private void ReadChapters(MoovInfo moovBox)
{
var soundBox = moovBox.Tracks.Where(b => b.Type == "soun").ToArray();
if (soundBox.Length == 0) return;
if (soundBox[0].Chaps != null && soundBox[0].Chaps.Length > 0)
{
var cb = new HashSet<uint>(soundBox[0].Chaps);
var textBox = moovBox.Tracks.Where(b => b.Type == "text" && cb.Contains(b.Id)).ToArray();
if (textBox.Length == 0) return;
ReadChaptersText(textBox[0]);
}
}
I'm creating WordProcessingDocuments using openxml (which works fine and the produced word doc is exactly what I want), now I'm trying to convert these newly created docs to HTML using the openxml Powertools. I'm new to this so I'm hoping thats it's something stupid that I'm missing but was hoping someone could point me in the right direction with these nullable errors I'm receiving.
This is the exact error...
System.NullReferenceException: Object reference not set to an instance of an object.
at OpenXmlPowerTools.HtmlConverter.ConvertToHtmlTransform(WordprocessingDocument wordDoc, HtmlConverterSettings settings, XNode node, Func2 imageHandler)
at OpenXmlPowerTools.HtmlConverter.<>c__DisplayClass37.<ConvertToHtmlTransform>b__1d(XElement e)
at System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext()
at System.Xml.Linq.XContainer.AddContentSkipNotify(Object content)
at System.Xml.Linq.XElement..ctor(XName name, Object content)
at OpenXmlPowerTools.HtmlConverter.ConvertToHtmlTransform(WordprocessingDocument wordDoc, HtmlConverterSettings settings, XNode node, Func2 imageHandler)
at OpenXmlPowerTools.HtmlConverter.<>c__DisplayClass37.<ConvertToHtmlTransform>b__1c(XElement e)
at System.Linq.Enumerable.WhereSelectEnumerableIterator2.MoveNext()
at System.Xml.Linq.XContainer.AddContentSkipNotify(Object content)
at System.Xml.Linq.XContainer.AddContentSkipNotify(Object content)
at System.Xml.Linq.XElement..ctor(XName name, Object[] content)
at OpenXmlPowerTools.HtmlConverter.ConvertToHtmlTransform(WordprocessingDocument wordDoc, HtmlConverterSettings settings, XNode node, Func`2 imageHandler)
I'm using the exact same code you can find on Eric Whites blog.
public static void PrintHTML(string file)
{
byte[] byteArray = File.ReadAllBytes(file);
using (MemoryStream memoryStream = new MemoryStream())
{
memoryStream.Write(byteArray, 0, byteArray.Length);
using (WordprocessingDocument doc =
WordprocessingDocument.Open(memoryStream, true))
{
HtmlConverterSettings settings = new HtmlConverterSettings()
{
//PageTitle = "some title"
};
XElement html = HtmlConverter.ConvertToHtml(doc, settings);
File.WriteAllText(#"C:\\Temp\Test.html", html.ToStringNewLineOnAttributes());
}
}
}
I know the code works because if i pass it a normal worddoc that I haven't created it works fine and converts to html fine. If i create a word doc using openxml then manually copy the contents into a new word file, save it, then pass it through the conversion code, that will work as well. So I'm thinking it must be something to do with the way I'm createing the word doc in openxml initially. Maybe im not adding a part to the file that is required.
Using the openxml sdk I have compared a working and non working file and they appear to have the same components/parts.
From the errors I've posted does anyone have any ideas of where the problem could be, ie, what is null? I can post the creation code for the word doc but it's quite extensive and it might just confuse people more.
I finally got to the bottom of this. I had to dig out the source code for the HtmlConverter in the openxmlpower tools, after some debuging I found that this line in the code was erroring...
line 371
styleId = (string)wordDoc.MainDocumentPart.StyleDefinitionsPart
.GetXDocument().Root.Elements(W.style)
.Where(e => (string)e.Attribute(W.type) == "paragraph" &&
(string)e.Attribute(W._default) == "1")
.FirstOrDefault().Attributes(W.styleId).FirstOrDefault();
basically in my debugging the
(string)e.Attribute(W._default)
was returning as True or False
so i changed the following line
.Where(e => (string)e.Attribute(W.type) == "paragraph" &&
(string)e.Attribute(W._default) == "1")
to
.Where(e => (string)e.Attribute(W.type) == "paragraph" && (
(string)e.Attribute(W._default) == "1" || (string)e.Attribute(W._default) == "true"))
and now works as expected
Had the same issue where I was saving a reportbuilder report to OpenWordXML and could not convert the bytes to html.
Had to add the following line of code for it to work correctly with version 2.8.1.0
private static IEnumerable<XElement> ParaStyleParaPropsStack(XDocument stylesXDoc,
string paraStyleName, XElement para)
{
if (stylesXDoc == null)
yield break;
var localParaStyleName = paraStyleName;
while (localParaStyleName != null)
{
XElement paraStyle = stylesXDoc.Root.Elements(W.style).FirstOrDefault(s
=>
**s.Attribute(W.type) != null &&**
s.Attribute(W.type).Value == "paragraph" &&
s.Attribute(W.styleId).Value == localParaStyleName);
s.Attribute(W.type) != null && // the liner that was added
I've got what seems to be a bug. I can add an entry to the database which has a single quote in the text.
However, when I search using QueryBuilder, for any text LIKE xyz, if xyz has a single quote in it, I get MySQL complaining about malformed SQL.
Other than parsing all strings myself, is there some method in Ormlite I can call to "santize" my strings?
Sample code is below:
public boolean isDuplicate () {
QueryBuilder<Company, Long> qb = getDao().queryBuilder() ;
Where<Company, Long> where = qb.where() ;
try {
if (Strings.isValid(name))
where.like("name", name) ;
if (Strings.isValid(regNo)) {
if (Strings.isValid(name))
where.or() ;
where.eq("regNo", regNo) ;
List<Company> res = where.query() ;
if (res != null && res.size() > 0)
return true ;
else
return false ;
}
} catch (SQLException e) {
GlobalConfig.log(e, true);
}
return false ;
}
This creates a SQL error if the company name has a single quote in it:
Creating default entries for Well Don't Delete Me 2 Please Pte Ltd.
[12-07-2013 13:45:42] You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 't Delete Me 2 Please Pte Ltd.' OR regNo = 'delete' )' at line 1
Any suggestions welcome.
Ok, I figured this out- I need to use the SelectArg method of querying the database.
So it now looks like this:
...
if (Strings.isValid(name))
{
SelectArg arg = new SelectArg () ; // Added
arg.setValue (name) ; / Added
where.like("name", arg) ; // Changed
}
if (Strings.isValid(regNo))
{
if (Strings.isValid(name))
where.or() ;
SelectArg arg = new SelectArg () ; // Added
arg.setValue (regNo) ; // Added
where.eq("regNo", arg) ; // Changed
List<Company> res = where.query() ;
if (res != null && res.size() > 0)
return true ;
else
return false ;
...
What I've learned is this: you must use one SelectArg PER item.
Now my question to Gray is why not make this a default behaviour? When I insert or update it seems to happen automatically, and to get the problem I found solved I have to add more
lines of code that could easily be part of the internal query handling.
I understand his concerns in this post but I agree with Dale. Maybe a halfway house is to have a flag to say which way Ormlite should treat parameters to the query methods.
I admire the flexibility and simplicity of the "programmable" SQL in Ormlite and in almost every case, Ormlite related code is concise, easy to follow and logical. This is one rare case where I feel it is more verbose than necessary, for no net benefit. Just my opinion.
In Eclipse, how can I get the package's children?
Consider this example:
+ org.stack
org.stack.test
- StackTest.java
- Stack.java
When we do IPackageFragment.getChildren() in org.stack, the Eclipse JDT only returns the compilation unit (Java Files)! But I want all children of a package: all ICompilationUnits and all Packages.
In this example when I apply IPackageFragment.getChildren() in org.stack, I want the org.stack.test and the ICompilationUnit Stack.java...
How can I do this?
IPackageFragment is not the correct starting point. You have to ask a higher level for the packages:
IPackageFragment: A single package. It contains ICompilationUnits or IClassFiles, depending on whether the IPackageFragmentRoot is of type source or of type binary. Note that IPackageFragment are not organized as parent-children. E.g. net.sf.a is not the parent of net.sf.a.b. They are two independent children of the same IPackageFragmentRoot.
Have a look at this article about the AST
Here's some code that should be close to what you needed. (Since we're a bit past 2011, I doubt it will help you much, but maybe it will help somebody else.) Doubtless it can stand some improvement.
Since it doesn't seem possible to directly recurse downward from the IPackageFragment (as mentioned by Kai), the basic idea is to get the higher level IPackageFragmentRoot and filter it's children based on the original fragment's path.
PackageFragment originFragment; // = org.stack's fragment
try {
String fragmentPath = originFragment.getPath().toString();
IJavaElement parent = originFragment.getParent();
ArrayList<IJavaElement> allChildren =
new ArrayList<IJavaElement>();
if (parent instanceof IPackageFragmentRoot) {
IPackageFragmentRoot root = (IPackageFragmentRoot)parent;
IJavaElement[] rootChildren = root.getChildren();
// originsFragments includes the origin and all package
// fragments beneath it
List<IJavaElement> originsFragments =
Arrays.asList(rootChildren).stream()
.filter(c -> c.getPath().toString().startsWith(fragmentPath))
.collect(Collectors.toList());
allChildren.addAll(originsFragments);
// Gather the children of the package fragments
for (IJavaElement o : originsFragments) {
if (o instanceof IPackageFragment ) {
IPackageFragment oFragment = (IPackageFragment)o;
IJavaElement[] fChildren = oFragment.getChildren();
allChildren.addAll(Arrays.asList(fChildren));
}
}
}
} catch (JavaModelException e) {
e.printStackTrace();
}
An alternative inelegant solution would be to start with the original fragment's path and then use Java's file and directory facilities to descend through the directory hierarchy. Then, you can use IJavaProject's findPackageFragment(IPath path) to connect to the proper IPackageFragments.
you need to do it in a recursive way.
here's some pseudo code
findAllClasses(package, classesCollection) {
for(Class c: package.getClasses)
classesCollection.add(c.getResourcePath)
if(package.hasChildPackages)
for(Package p: packages)
findAllClasses(p, classesCollection)
}
I am new to Emacs, and
I have the following code as a sample.
I have installed GNU Emacs 23.1.1 (i386-mingw-nt6.1.7600), installed cedet-1.0pre7.tar.gz. , installed ELPA, and company.
You can find my simple Emacs configuration at the bottom.
The problem is, when I type q[0] in main() and press . (dot), I see the 37 members of the vector, not Person although first_name and last_name are expected. The completion works as expected in the function greet() but it has nothing to do with vector.
My question is, how can I accomplish code completion for vector elements too?
#include <iostream>
#include <vector>
using namespace std;
class Person
{
public:
string first_name;
string last_name;
};
void greet(Person a_person)
{
// a_person.first_name is completed as expected!
cout << a_person.first_name << "|";
cout << a_person.last_name << endl;
};
int main()
{
vector<Person> q(2);
Person guy1;
guy1.first_name = "foo";
guy1.last_name = "bar";
Person guy2;
guy2.first_name = "stack";
guy2.last_name = "overflow";
q[0] = guy1;
q[1] = guy2;
greet(guy1);
greet(guy2);
// cout q[0]. I want to see first_name or last_name here!
}
My Emacs configuration:
;;; This was installed by package-install.el.
;;; This provides support for the package system and
;;; interfacing with ELPA, the package archive.
;;; Move this code earlier if you want to reference
;;; packages in your .emacs.
(when
(load
(expand-file-name "~/.emacs.d/elpa/package.el"))
(package-initialize))
(load-file "~/.emacs.d/cedet/common/cedet.el")
(semantic-load-enable-excessive-code-helpers)
(require 'semantic-ia)
(global-srecode-minor-mode 1)
(semantic-add-system-include "/gcc/include/c++/4.4.2" 'c++-mode)
(semantic-add-system-include "/gcc/i386-pc-mingw32/include" 'c++-mode)
(semantic-add-system-include "/gcc/include" 'c++-mode)
(defun my-semantic-hook ()
(imenu-add-to-menubar "TAGS"))
(add-hook 'semantic-init-hooks 'my-semantic-hook)
This is a known problem with the Semantic analyzer. I currently cannot deal with Template Specialization, which is used in the gcc STL (your problem stems from such a specialization in allocator.h). This has been discussed on the mailing list:
http://thread.gmane.org/gmane.emacs.semantic/2137/focus=2147
GCCSense
An example of completion of a C++ code in Emacs: