GTK+ noob question here:
Would it be possible to customize the GtkFileChooserButton or GtkFileChooserDialog to remove the 'Places' section (on the left) and the 'Location' entry box on the top?
What I'm essentially trying to do is to allow the user to select files only from a particular folder (which I set using gtk_file_chooser_set_current_folder ) and disable navigating to other locations on the file system.
This is the standard file chooser dialog :
This is what I need:
It doesn't look like that is possible with the standard file chooser dialog. For example, here is a document discussing why such a thing would be useful and how it could be implemented, but the idea never made it to fruition.
What you can do, perhaps, is write your own dialog that implements the GtkFileChooser interface, based on the GtkFileChooserDialog code, but hides the location bar and bookmarks list.
You can get a handle on the individual children by finding out where there are with gtkparasite and then accessing them with get_children.
Make sure to use .show() instead of .run() for inspecting the dialog with gtkparasite. If you use .run() the dialog is shown in modal mode so you can't inspect it.
For example I hide the Path and Places widgets with the statements below:
dialog = gtk.FileChooserDialog("Open***", None, gtk.FILE_CHOOSER_ACTION_OPEN,
(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN, gtk.RESPONSE_OK))
dialog.set_show_hidden(True)
dialog.set_default_response(gtk.RESPONSE_OK)
vbox = dialog.get_children()[0].get_children()[0].get_children( [0].get_children()[0]
vbox.get_children()[0].hide()
vbox.get_children()[2].get_children()[0].hide()
Of course this is not an exposed API so it can always break from underlying changes.
Hope it makes sense ...
Tried to post an image but I am a new user ....
Related
I want to use an editor to display a log from a program, I just need a very basic text field:
With a vertical scrollbar
With a contextual menu for copy/paste
Prevent the user from changing the text
In order to activate the copy/paste menu, I use the class racket:text% from framework rather than the basic one.
How to prevent the user from changing the text?
I read the documentation, as far as I understand the closest thing I found is lock method:
https://docs.racket-lang.org/gui/editor___.html?q=lock#%28meth._%28%28%28lib._mred%2Fmain..rkt%29._editor~3c~25~3e%29._lock%29%29
But it is not convenient, as it also prevent my program to write the data.
I also find get-read-write? but cannot find set-read-write.
Use the lock method, and just unlock the editor around any modifications that you want to do. You may find it useful to write a call-with-unlock helper function or with-unlock macro.
If you do your updates from the eventspace's handler thread (and you probably should; use queue-callback if they originate from another thread), then as long as you re-lock the editor at the end of an update, the user will never be able to interact with the unlocked editor.
What is the proper way to use the SDK to make a dialog (which is not anchored to the add-on bar, etc. but shows centered on screen)? It doesn't seem like there is any API for this important capability. I do see windows/utils has open but I have two problems with that:
The dialog opening seems to require "chrome" privs to get it to be centered on the screen (and I'd be expectant of add-on reviewers complaining of chrome privs, and even if not, I'd like to try to stick to the SDK way).
While I can get the DOM window reference of the new window/utils' open() dialog, I'm not sure how to attach a content script so I can respond to user interaction in a way that prompts (and can respond to) privileged behavior ala postMessage or port.emit (without again, directly working with chrome privs).
Ok, this answer should have been pretty obvious for anyone with a little experience with the SDK. I realized I can just use a panel. In my defense, the name "panel" is not as clear as "dialog" in conjuring up this idea, and I am so used to using panels with widgets, that it hadn't occurred to me that I could use it independently!
Edit
Unfortunately, as per Bug 595040, these dialogs are not persistent, meaning if the panel loses focus, the "dialog" is gone... So panel looks like it is not a suitable candidate after all... :(
Edit 2
I've since moved on and have gotten things working mostly to my satisfaction with sdk/window/utils and openDialog on whose returned window I add a load listener and then call tabs.activeTab.on('ready', and then set tabs.activeTab.url to my add-on local HTML file so the ready event will get a tab to which I can attach a worker. There is still the problem with chrome privs I suppose, but at least the main communications are using SDK processes.
Update to Edit 2:
Code sample provided by request:
var data = require('sdk/self').data,
tabs = require('sdk/tabs');
var win = require('sdk/window/utils').openDialog({
// No "url" supplied here in this case as we add it below (in order to have a ready listener in place before load which can give us access to the tab worker)
// For more, see https://developer.mozilla.org/en-US/docs/Web/API/window.open#Position_and_size_features
features: Object.keys({
chrome: true, // Needed for centerscreen per docs
centerscreen: true, // Doesn't seem to be working for some reason (even though it does work when calling via XPCOM)
resizable: true,
scrollbars: true
}).join() + ',width=850,height=650',
name: "My window name"
// parent:
// args:
});
win.addEventListener('load', function () {
tabs.activeTab.on('ready', function (tab) {
var worker = tab.attach({
contentScriptFile: ....
// ...
});
// Use worker.port.on, worker.port.emit, etc...
});
tabs.activeTab.url = data.url('myHTMLFile.html');
});
if the panel loses focus, the "dialog" is gone...
It doesn't get destroyed, just hides, right? If so, depending on why it's getting hidden, you can just call show() on it again.
You'd want to make sure it's not being hidden for a good reason before calling show again. If there's a specific situation in which it's losing focus where you don't want it to, create a listener for that situation, then call if (!panel.isShown) panel.show();
For example, if it's losing focus because a user clicks outside the box, then that's probably the expected behaviour and nothing should be done. If it's losing focus when the browser/tab loses focus, just register a tab.on('activate', aboveFunction)
Simply adding ",screenX=0,screenY=0" (or any values, the zeroes seem to be meaningless) to the features screen seems to fix centerscreen.
GWT's Editor framework is really handy and it can not only be used for editing POJOs but also for read-only display.
However I am not entirely sure what the best practice is for doing inline edits.
Let's assume I have a PersonProxy and I have one Presenter-View pair for displaying and editing the PersonProxy. This Presenter-View should by default display the PersonProxy in read-only mode and if the user presses on a edit button it should allow the user to edit the PersonProxy object.
The solution I came up with was to create two Editors (PersonEditEditor and PersonDisplayEditor) that both added via UiBinder to the View. The PersonEditEditor contains
ValueBoxEditorDecorators and the PersonDisplayEditor contains normal Labels.
Initially I display the PersonDisplayEditor and hide PersonEditEditor.
In the View I create two RequestFactoryEditorDriver for each Editor and make it accessable from the Presenter via the View interface. I also define a setState() method in the View interface.
When the Presenter is displayed for the first time I call PersonDisplayDriver.display() and setState(DISPLAYING).
When the user clicks on the Edit button I call PersonEditDriver.edit() and setState(EDITING) from my Presenter.
setState(EDITING) will hide the PersonDisplayEditor and make the PersonEditEditor visible.
I am not sure if this is the best approach. If not what's the recommended approach for doing inline edits? What's the best way to do unit-testing on the Editors?
If you can afford developing 2 distinct views, then go with it, it gives you the most flexibility.
What we did in our app, where we couldn't afford the cost of developing and maintaining two views, was to bake the two states down into our editors, e.g. a custom component that can be either a label or a text box (in most cases, we simply set the text box to read-only and applied some styling to hide the box borders).
To detect which mode we're in, because we use RequestFactoryEditorDriver (like you do), we have our editors implement HasRequestContext: receiving a null value here means the driver's display() method was used, so we're in read-only mode. An alternative would be to use an EditorVisitor along with some HasReadOnly interface (which BTW is exactly what RequestFactoryEditorDriver does to pass the RequestContext down to HasRequestContext editors).
Yes,Presenter-View pair should be. But Here two ways to achieve this feature if you like to go with:
1) Integrate Edit/View code design in one ui.xml i.e.Edit code in EDitHorizonatlPanel and View code in ViewHorizontalPanel.The panel has different id. By using id, show/hide panel with display method. if getView().setState() ==Displaying then show ViewHorizontalPanel and if getView().setState()==Editing then show EditHorizontalPanel.
2) Instead of using labels, Use textboxes only. set Enable property is false when you need it in view mode otherwise true
You have created two Presenter/view but I think if Edit/View function has similar code so no need to rewrite similar code again and again for view purpose.
If a big project has so many Edit/View function and you will create such type of multiple View/Presenter than your project size become so huge unnecessary.
I think that whatever I have suggest that might be not good approach but a way should be find out which help to avoid code replication.
The object is to Show-Hide text located under their respective Titles, so a User reads the title and shows or hides text belonging to that title if the User wants to read more.
I tried whatever I could find so far on here, we're talking dynamically setting text coming from a spreadsheet, can't use IDs, must work with .class, must be missing something, I have this piece of code:
... html.push('<div class="comments">' + comment + '</div></div></div>');
but when I try this Show-Hide code nothing happens, even if the error console shows nothing. Basically I want to Show-Hide the .comments class divs with a show-hide toggle link located under each of them. I say them because the .comments divs are reproduced dynamically while extracting text coming from Google spreadsheet cells/row (one .comments div per spreadsheet row). I tried .next, child and parent but they all divorced me so I dunno looks like a dynamic issue. So far I only managed to globally toggle all divs to a visible or hidden state but I need to toggle independantly individual divs.
I prefer a jQuery solution but whatever worked so far was achieved with native javascript.
Note: If a cross-browser truncate function which would append a more-less link after a number of words (var) in each .comments divs would be easier to implement then I would gladly take that option. Thx for any help, remember I am still learning lol!
I have been working on an entirely JS UI project and have brought myself to using $('', { properties }).appendTo(BaseElement) to work best for adding HTML elements because it appropriately manipulates the DOM every time.
If you are having good luck with push elsewhere, however, breakpointing on the line where you do your $('.class').hide() and see what $('.class').length is. Alternately, you can just add alert($('.class').length) to your code if you are unable to breakpoint the code. If it is 0, then your elements have not been properly added to the DOM. Changing to append will ensure they are part of the DOM and therefore targetable via JQuery.
I am planning on using ShareKit in my App. I would also like to have printing (AirPrint). I was thinking to have all options( Facebook & Twitter & Printer ) in the same actionsheet.
Is there any reason why I shouldn't do that?
I have been looking for some tips on how to achieve this but have come up blank. There are tips to remove things from the ActionSheet but not add them. Would a printer option no be considered 'sharing'?
The process of adding an action to ShareKit is covered in "How to Add a New Action to ShareKit" This description assumes you have already implemented a core Sharekit functionallity (for example, you have implemented the ShareKit example program).
You will copy New Action templates from the ShareKit Template Src folder (.m and .h files) into your project, rename the files with the appropriate name (like "SHKPrint.m/.h"). There are some obvious things to change, like the class name and the header import file. Add #import "SHKSharer.h" to the header file.
Add the class to the actions/services list in SHKSharers.plist, as the linked page describes. (There really is no distinction at this point between an action and a service that I can see, and they may as well be grouped together, as far as I can tell, without problem. One distinction, though, is that actions are presumed to not require authentication. requiresAuthentication is method in the template.)
After that, as the documentation says, get familiar with Understanding the share flow.
At least one of the canShare methods needs to be overridden, and they are already set up in the template for you to modify and uncomment. I imaging that for your purpose, you might want to consider canShareText as an appropriate method to share, so change that one to return YES. Then you will be able to print using a printFormatter assigned to either UISimpleTextPrintFormatter or UIMarkupTextPrintFormatter (but not without setting up a UIPrintInteractionController). (I don't think you mentioned what you want to print, so you'll have to improvise.)
Modify the sharerTitle method in your new new sharer class, to show an appropriate title.
At this point, you should be able to run your code and see an action sheet. Your print action won't show up on this one, but if you click the more... button, it should show up on the second sheet.
Click that action and nothing will happen yet except the sheet will hide. Now you need to add some code to do the printing. (You will see later, if you choose to share again, the new action has been added to the first action sheet, which is a most-recently-used list.)
I mentioned that it was assumed you have already implemented a core ShareKit functionality, such as the ShareKit example program. If you go to the method that invokes the sharekit action sheet (in your own code, such as responding to your pressing the share button), you will see a place to establish what kind of information you want to share -- e.g., URL, image, text, ... This is independent of where you want to send your shared information -- printer, facebook, twitter, ... (which I think puts the cart before the horse, and I have modified my own implementation to fix this.) But, ignoring that for the time being, you will want to set it up something like this:
- (void) shareButtonPressed {
SHKItem *item = [SHKItem text:yourSimpleTextOrMarkupText];
// Get the ShareKit action sheet
SHKActionSheet *actionSheet = [SHKActionSheet actionSheetForItem:item];
// Display the action sheet
[actionSheet showInView:self.view];
}
This puts the wheels into motion to share whatever is in the item object. The item object includes a shareType, which in this case is SHKShareTypeText, which is an enumerated type.
I won't go into the machinery that translates this into the shared result. I don't know it in my sleep yet, and might mislead you (if I haven't already).
When you click on the item in the action sheet, the SHKActionSheet class does some magic, converting the string name of your new action class (SHKPrint in this case) into a class, and using that to invoke a class method to allocate and initialize an instance of the same class. (I am doing this as I type, so I skipped the step on how this is accomplished from the "more..." second sheet. I'll leave it to the reader to trace that and see how it works.)
The sharing is done through a call chain running through share, then show methods in the SHKSharer class. (There is some business about autosharing that I won't get into here, but I think you can ignore that for the time being.) This finally lands on the send method of your custom class (SHKPrint). Look at your template file, and it will give you some guidance on what to do.
For more information on printing, see this link, which seems to give a pretty good example of what you can do to print.
I'll stop here for a couple of reasons. I think I answered your question, how to add an action sheet. Also, I don't have AirPrint capability to test with here, so I can't really go much further on my own.
Let me know if you have any other questions.