I'm trying to extend the behaviour of ttk::combobox to make it behave like the Google search box in my browser - i.e. I'd like it to drop down automatically and limit the entries in the listbox to those which match the string that I've typed in so far. Ultimately, I'd like to select the part of the string that's been autocompleted so that the next character the user types will cause it to be deleted and re-start the matching process.
I found the page on the Tcler's wiki, but that appears to select the entry with the letter just typed, which isn't what I want. (Consider a user selecting from a list of US States. When they type A, I want the selection to be limited to Alabama, Alaska, Arizona and Arkansas; when they then type an L, the list should be limited to Alabama and Alaska. The code on the wiki would select Alabama when the user types A, then Louisiana when they type L.)
I tried defining a few bindings on the ttk::combobox, but gave that up - to be honest, I can't remember why - and have tried to extend the behaviour of a ttk::entry to cover it.
After borrowing liberally from ttk/combobox.tcl I've managed to post a listbox and to limit the entries in the listbox, but am having big problems now that I've added bindings to make the up and down arrows alter the selection. To be precise, the selected item is moved happily, but some of the time when the entry widget loses focus, the whole application hangs up and my tclsh soaks up all the CPU.
I'm developing using ActiveTcl 8.6 on both Windows and Linux and the code seems to behave the same on both platforms, although I haven't tried on Linux since I first saw it not hanging in Windows. I'd be very happy to share my code, but since the demo script runs to about 450 lines, I wouldn't read it myself if someone else posted that much.
Can anyone help by asking the right question to set off a lightbulb for me? The problem feels like a timing problem, but I've no idea where to start trying to track it down.
Many thanks.
Edit I've been racking my brain, and I think the reason I abandonned the attempt to extend ttk::combobx was because there were already a large number of bindings in place, and some did things that I didn't want. The current effort uses a validatecommand on the entry widget and Key-Up, Key-Down, FocusIn and FocusOut bindings.
Current code is on pastebin here.
Well, that was embarrassing!
I took another look at the code on the wiki and discovered that it did the thing I most wanted. It doesn't post the listbox, but it does autocomplete, and if you attempt to navigate the (unposted) listbox, by pressing Key-Up or Key-Down, it starts off with the appropriate item highlighted.
That's quite enough for what I need; if I decide I really must have the listbox posted, I can see about that at the time. (Given my bad experience trying to roll my own, however, I suspect that I'll just live with this.)
Many thanks for the forebearance and suggestions.
Related
I really enjoy using Chrome's URL bar because it remembers commonly-visited sites and often suggests a good completion based on what I've typed and/or visited before. So, for example, I can type t in the URL bar and Chrome will automatically fill it in with twitter.com, or I can type maps and Chrome will fill in the .google.com. This gives me the convenience of data-driven domain name shortcuts without having to maintain an explicit list.
What I'm wondering, though, is how Chrome determines that an old shortcut should be replaced with a new one. For example, if I visit twitter.com often, then that becomes the completion when I type t. But if I then start visiting twilio.com often enough, then, after some time, Chrome will start to fill that in as the default completion for t. What I can't figure out is how or when that transition takes place. It also seems that there are (at least) two cases involved : one for domain names, and another for path strings, because if I visit a certain full URL often, and then want to get to the root of the same domain, I end up having to type the entire domain name out to get Chrome to ignore the full-URL completion.
If I had to guess, I'd imagine that Chrome stores the things that I type in the URL bar in a trie whose values are the number of times that a particular string has been typed (and/or visited ?). Then I'd imagine it has some sort of exponential decay model for the "counts" in the trie. But this is just a guess. Does anyone know how this updating process happens ?
Well, I ended up finding some answers by having a look at the Chromium source code ; I'd imagine that Chrome itself uses this code without too much modification.
When you type something into the search/URL bar (which is apparently called the "Omnibox"), Chrome starts looking for suggestions and completions that match what you've typed. To do this, there are several "providers" registered with the browser, each of which knows how to make a particular type of suggestion. The URL history provider is one of these.
The querying process is pretty cool, actually. It all happens asynchronously, with particular attention paid to which activity happens in which thread (the main thread being especially important not to block). When the providers find suggestions, they call back to the omnibox, which appears to merge and sort things before updating the UI widget.
History provider
It turns out that URLs in Chrome are stored in at least one, and probably two, sqlite databases (one is on disk, and the second, which I know less about, seems to be in memory).
This comment at the top of HistoryURLProvider explains the lookup process, complete with multithreaded ASCII art !
Sqlite lookup
Basically, typing in the omnibox causes sqlite to run this SQL query for looking up URLs by prefix. The suggestions are ordered by the number of visits to the URL, as well as by the number of times that a URL has been typed.
Interestingly, this is not a trie ! The lookup is indeed based on prefix, but the scoring of those lookups does not appear to be aggregated by prefix, like I'd imagined.
I had a little less success in determining how the scores in the database are updated. This part of the code updates a URL after a visit, but I haven't yet run across where the counts are decremented (if at all ?).
Updating suggestions
What I think is happening regarding the updating of suggestions -- and this is still just a guess right now -- is that the in-memory sqlite database essentially has priority over the on-disk DB, and then whenever Chrome restarts or otherwise flushes the contents of the in-memory DB to disk, the visit and typed counts for each URL get updated at that time. Again, just a guess, but I'll keep looking as I get time.
The code is really nice to read through, actually. I definitely recommend it if you have similar questions about Chrome.
I have a pretty good project task management system going in Microsoft Access, but one feature I'm still missing is some type of 'quick entry' like facility often found in many good productivity applications.
This is how it would work:
Scenario 1:
You're in another application, working on a few things, and you just remember something that needs to get done. You hit your predefined shortcut: CTRL + ALT + T (again, from outside Microsoft Access) and it brings up a small access form with a text box in to which you can type what needs to get done, e.g.
Inform key stakeholders of concerns regarding timeline
you hit return and that gets saved as a record in Microsoft Access instantly.
An alternative, and slightly more complex scenario...
Scenario 2:
As above, but you want to add further details besides the task name, such as the person you need to speak to, and a due date. The input in to the text box could look like this:
Inform #Sally of concerns regarding timeline >+3
Where '#' tells access to populate a field called 'Contact' with 'Sally' (unless it already exists) and '>+3' is interpreted by access to mean a due date 3 days from today.
How difficult are Scenario 1 and Scenario 2 to perform? What level of VBA/programming knowledge would be required?
Thanks,
I would say it requires a fair amount of confidence in VBA.
You need to register a global hot-key; that is, a keyboard-combination that can be captured from outside the Access application. It requires win-api calls. Here is some code.
You need to know where to place these calls. I believe you have to put them in a standard module, not in the form's class module. (I haven't double-checked this, it's late.)
You need to have a little understanding about what this code is doing. NEVER attempt to type this api-code - copy it from a reliable source, exactly as it is!! You don't need to fully understand the code, but you need to know how (and when) to call each function.
Once you've registered the hot-key then your VBA needs to bring your application to the front and display your form, and focus it. Reliably bringing the application to the front may also require api-calls.
Once your form is opened (and focused) you can have a button on it to parse the information in its textbox. However, if you are designing the form anyway, I would add checkboxes, comboboxes, etc., rather than trying to parse a complex sentence/ statement.
I have an application in which i am trying to create autocompletion of jTextField and jTable from database values as we do in address bar of browsers. I tried many ways,but i couldnt complete it. Do any one know how to do this in a simple way, the links and notes which i had got was quite confusing for me. I am using java and MySQl in netbeans.Hoping a reply soon..
Thank you
You can give JIDE JIDE Common Layer at http://www.jidesoft.com/products/oss.htm a try. It is free and open source. There are two features you might be interested in. Both are in JIDE Common Layer. One is AutoCompletion feature which can auto-complete based on a known list while you are typing (no drop down). The other is IntelliHint feature which will show a list of matching choices in a drop down while you are typing. Since you mention something like address bar of a browser, I would recommend IntelliHint. Hope it helps.
I am a student at a University. With the placement process going on, we have an internal placement website that shows updates and status about various companies I have applied to. Since the number of companies is too large it becomes cumbersome to scroll through the complete list to find information. Sometimes, I just miss some things. Now, to tackle this problem, here is what I want to do:
The data is in an HTML table. Each row shows information about one company: Some dates, Status(Not/Shortlisted/Applied), Some yes/no options etc. each in a different column. Once I open the page I want to be able to extract information about which companies I got shortlisted in, and in which ones I didn't make it.
What is the right technology to do this ? I am thinking of writing a Greasemonkey user script (I have never actually written any, but how hard could it be ?). What other options do I have?
Edit: I don't quite understand why this question has voted to be closed?
I just displayed a use case for something general: On opening a web page, automatically extracting information from the page and display it to the user. What is the easiest and sufficiently powerful way to achieve this?
Since you can't get access to the website's database, Greasemonkey would be your best automation approach. However, this task is likely to be over before you can get a decent script up from scratch.
Your best practical approach is to save the pages and/or copy and summarize the data in MS Excel, or equivalent.
~~~~~~~~~
Here at SO, We will not develop any but the simplest Greasemonkey scripts for you from scratch (unless they are fun somehow ;) ). But, you can sometimes get such help in the "Script requests forum" at userscripts.org.
In order for someone to help you, they will need:
A clear idea of exactly what data gets manipulated, and how.
Access to the target site. Or access to saved snapshots of the target pages. GM scripts are extremely dependent on the details of the target page.
"other option":
ctrl + F
enter shortlisted
enter
ctrl + G <--repeat last search
For a major school project I am implementing a real-time collaborative editor. For a little background, basically what this means is that two(or more) users can type into a document at the same time, and their changes are automatically propagated to one another (similar to Etherpad).
Now my problem is as follows:
I want to be able to detect what changes a user carried out onto an HTML textfield. They could:
Insert a character
Delete a character
Paste a string of characters
Cut a string of characters
I want to be able to detect which of these changes happened and then notify other clients similar to "insert character 'c' at position 2" etc.
Anyway I was hoping to get some advice on how I would go about implementing the detection of these changes?
My first attempt was to consider the carot position before and after a change occurred, but this failed miserably.
For my second attempt I was thinking about doing a diff on the entire contents of the textfields old and new value. Am I missing anything obvious with this solution? Is there something simpler?
It is a really hard work make this working today, for several reasons, but
maybe you will need to restrict only to some browsers. read: https://developer.mozilla.org/en/XUL/Attribute/oninput the alternative to "oninput" is listen to all input events (keyboard, mouse, dragdrop) I suggest to use "oninput"
html is not perfect... even html5. input and textareas supports only single-range
selections. you can solve this using designmode/contenteditable instead of
textareas/textfield
detecting offsets of what changed is a hard work: read
-- https://developer.mozilla.org/en/Document_Object_Model_%28DOM%29/window.getSelection
-- http://www.quirksmode.org/dom/range_intro.html -- http://msdn.microsoft.com/en-us/library/ms535869%28v=VS.85%29.aspx -- http://msdn.microsoft.com/en-us/library/ms535872%28v=VS.85%29.aspx
you may need a "diff" algorithm written in javascript! http://ejohn.org/projects/javascript-diff-algorithm/
one personal note: detecting words, characters changes may be totally non-sense and not useful, detect instead paragraphs changes, or in case of an excel-like worksheet, the single cell
I hope this helps
feel free to correct my English!
My pseudocode/written out response would be (if I understand your question exactly) to use jQuery to detect keyup events and then save the input to the server via ajax, then also take the response and post it back to the input. This isn't very efficient, but basically the idea is that you're constantly posting and checking what else has been posted. If you want to see what someone else is doing in real time, you can ping the server every second or so and update with the response.
All of this of course can be optimized, but it still is kind of taxing for a server. You could also see if you can implement Google Topeka Wave for your project, or get in touch with Google Topeka to see how they do it :)