I get an error (Gtk-WARNING **: 18:33:56.632: Attempting to add a widget with type GtkBox to a GtkDialog, but as a GtkBin subclass a GtkDialog can only contain one widget at a time; it already contains a widget of type GtkBox)
when executing this code:
def switchfile(self, widget):
self.cd = None
self.cd = {
'win' : Gtk.Dialog(),
'entry' : Gtk.Entry(),
'btnok' : Gtk.Button.new_from_icon_name("document-open-symbolic", Gtk.IconSize.MENU),
'label' : Gtk.Label(),
'vbox' : Gtk.Box(orientation=Gtk.Orientation.VERTICAL),
'hbox' : Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
}
self.cd['entry'].set_placeholder_text('Notebook Name')
self.cd['btnok'].connect('clicked', self.switch_yes)
self.cd['hbox'].pack_start(self.cd['entry'], True, True, 0)
self.cd['hbox'].pack_start(self.cd['btnok'], True, True, 0)
self.cd['vbox'].pack_start(self.cd['label'], True, True, 0)
self.cd['vbox'].pack_start(self.cd['hbox'], True, True, 0)
self.cd['vbox'].show_all()
self.cd['win'].add(self.cd['vbox'])
self.cd['win'].show_all()
self.cd['win'].run()
But, if there already is a Gtk.Box in the Gtk.Dialog, how can I access it?
In another Question on Stackoverflow, there was a Dialog.get_vbox()function, but it was C/C++ and when i use bpython3 to list the functions in Gtk.Dialog, it has nothing, no get_vbox(), an also nothing else like get_vbox: no get_box()' and no get_container()`.
How can I access the Gtk.Box in Gtk.Dialog
Information:
I am using Version 3.0 of gi.repository.Gtk
Now I found out how to do it.
def switchfile(self, widget):
self.cd = None
self.cd = {
'win' : Gtk.Dialog(),
'entry' : Gtk.Entry(),
'btnok' : Gtk.Button.new_from_icon_name("document-open-symbolic", Gtk.IconSize.MENU),
'label' : Gtk.Label(),
'vbox' : None,
'hbox' : Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
}
self.cd['win'].add_buttons(
Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Gtk.STOCK_OK, Gtk.ResponseType.OK
)
self.cd['vbox'] = self.cd['win'].get_content_area()
self.cd['entry'].set_placeholder_text('Notebook Name')
self.cd['btnok'].connect('clicked', self.switch_yes)
self.cd['hbox'].pack_start(self.cd['entry'], True, True, 0)
self.cd['hbox'].pack_start(self.cd['btnok'], True, True, 0)
self.cd['vbox'].pack_start(self.cd['label'], True, True, 0)
self.cd['vbox'].pack_start(self.cd['hbox'], True, True, 0)
self.cd['vbox'].show_all()
self.cd['win'].show_all()
self.cd['win'].run()
Important is this line:
self.cd['vbox'] = self.cd['win'].get_content_area()
I didn't know about that function, but this is how to access the Gtk.Box in Gtk.Dialog objects.
I'm trying to populate the value for the agSetColumnFilter, but I'm getting an error that I cannot find anything where in documentation (or anywhere online). Has anyone ever run into this issue?
This is what the column definition looks like:
columnDefs.push({
headerName: col.name,
field: col.name,
def: col,
rowGroup: k < groupedColumnCount ? true : false,
pinned: k < _this.groupBy.length ? 'left' : null,
lockPinned: k < _this.groupBy.length ? true : false,
hide: k < groupedColumnCount ? true : false,
suppressToolPanel: _this.groupBy.length ? true : false,
valueGetter: function(data){
if(data.data){
var def = data.colDef.def;
var value = data.data[data.colDef.field];
if(value){
return value.value;
}else{
return null;
}
}else{
return data.value;
}
},
valueFormatter: function(data){
if(data.data){
var def = data.colDef.def;
var value = data.data[data.colDef.field];
if(!value) return null;
if(value.formatted){
_this.cache[data.colDef.field + value.value] = value.formatted;
}
return value.formatted ? value.formatted : value.value;
}else{
if(_this.cache[data.colDef.field + data.value]){
return _this.cache[data.colDef.field + data.value];
}else{
return data.value;
}
}
},
keyCreator: function(params){
console.log(params);
},
filter: 'agSetColumnFilter',
filterParams: {
values: function (params) {
params.success([{
$uri: 'nhuihi',
value: {
$value: 'some text'
}
}]);
}
}
});
I'm only printing out keyCreator params for now since I don't know what will actually be available in the data. The idea is that I can set values using complex objects returned from the server and display a formatted value instead of a key. This is the error I'm getting.
ag-grid-enterprise.min.noStyle.js:formatted:27684 Uncaught TypeError: Cannot read property 'onFilterValuesReady' of undefined
at t.setFilterValues (ag-grid-enterprise.min.noStyle.js:formatted:27684)
at e.modelUpdatedFunc (ag-grid-enterprise.min.noStyle.js:formatted:27609)
at e.onAsyncValuesLoaded (ag-grid-enterprise.min.noStyle.js:formatted:27917)
at values (comparison-table-v7.js:1253)
at e.createAllUniqueValues (ag-grid-enterprise.min.noStyle.js:formatted:27909)
at new e (ag-grid-enterprise.min.noStyle.js:formatted:27867)
at t.initialiseFilterBodyUi (ag-grid-enterprise.min.noStyle.js:formatted:27608)
at t.init (ag-grid-enterprise.min.noStyle.js:formatted:18945)
at e.initialiseComponent (ag-grid-enterprise.min.noStyle.js:formatted:10602)
at e.createAgGridComponent (ag-grid-enterprise.min.noStyle.js:formatted:10574)
Here's a test case for it as well. I simply modified the example by AG Grid. https://plnkr.co/edit/GURQHP0KKFpJ9kwaU83M?p=preview
If you open up console, you will see an error when you click on Athletes filter.
Also reported on GitHub: https://github.com/ag-grid/ag-grid/issues/2829
If you need to configure filter values without async requests
filterParams: {
values: getFilterValuesData()
}
getFilterValuesData(){
//data preparation
//little bit modified sample to present that you can handle your logic here
let data = [];
[
'John Joe Nevin',
'Katie Taylor',
'Paddy Barnes',
'Kenny Egan',
'Darren Sutherland',
'Margaret Thatcher',
'Tony Blair',
'Ronald Regan',
'Barack Obama'
].forEach(i=>{
data.push(i);
});
return data;
}
If it requires to make an async request for data preparation you can use callback function:
filterParams: {
values: (params)=>{
setTimeout(()=>{ -- setTimeout on this case only for async request imitation
params.success(['value 1', 'value 2'])
}, 5000)
}
}
Notice: params.success(...) should be used only with an async request
Doc: ag-grid Asynchronous Values
I've got a component which puts an editable polygon on the map. When the user hits the "save" button, I want to access an array of the polygon's new vertices, so that I can save them. How do I do this?
My component:
<FeatureGroup>
<EditControl
position="topright"
onEdited={e => console.log(e)}
edit={{ remove: false }}
draw={{
marker: false,
circle: false,
rectangle: false,
polygon: false,
polyline: false
}}
/>
<Polygon positions={polygonCoords} />;
</FeatureGroup>
The couple of references I've got:
https://github.com/alex3165/react-leaflet-draw
https://leaflet.github.io/Leaflet.draw/docs/leaflet-draw-latest.html#l-draw-event-draw:editstop
I understand I have to implement some sort of function dealing with the onEdited hook and the event generated thereby, but does anyone have any idea how I can get the new vertex array from this event?
For anyone else struggling with this, here's a working solution with ES6:
<FeatureGroup>
<EditControl
position="topright"
//this is the necessary function. It goes through each layer
//and runs my save function on the layer, converted to GeoJSON
//which is an organic function of leaflet layers.
onEdited={e => {
e.layers.eachLayer(a => {
this.props.updatePlot({
id: id,
feature: a.toGeoJSON()
});
});
}}
edit={{ remove: false }}
draw={{
marker: false,
circle: false,
rectangle: false,
polygon: false,
polyline: false
}}
/>
<Polygon positions={[positions(this.props)]} />;
</FeatureGroup>
);
Getting this took me some hours so it might be helpful to someone someday.
First initialise mapLayer state to hold your coordinates and implement onCreated() and onEdited() functions
const [mapLayers, setMapLayers] = useState([]);
const onCreated = e => {
console.log(e)
const {layerType, layer} = e
if (layerType === "polygon") {
const {leaflet_id} = layer
setMapLayers(layers => [...layers, {id: leaflet_id, latlngs: layer.getLatLngs()[0]}])
}
};
const onEdited = e => {
// console.log('Edited data', e);
const {layers: {_layers}} = e;
Object.values(_layers).map((
{_leaflet_id, editing}) => {
setMapLayers((layers) => layers.map((l) => l.id === _leaflet_id? {...l, latlngs: {...editing.latlngs[0]}
} : l)
)
});
};
I would like to expand the Gtk.Scale widgets (they are inside a Gtk.ListBox) and get rid of the indentation of the bottom two. The indentation seems to be connected to the length of the text in the left column.
#!/usr/bin/python3
from gi.repository import Gtk
from matplotlib.figure import Figure
from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas
from matplotlib.backends.backend_gtk3 import NavigationToolbar2GTK3 as NavigationToolbar
from numpy import pi
window = Gtk.Window()
window.set_default_size(800, 500)
window.connect("delete-event", Gtk.main_quit)
boxvertical = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
window.add(boxvertical)
toolbar = Gtk.Toolbar()
context = toolbar.get_style_context()
context.add_class(Gtk.STYLE_CLASS_PRIMARY_TOOLBAR)
boxvertical.pack_start(toolbar, False, True, 0)
horizontalbox = Gtk.Box()
boxvertical.pack_start(horizontalbox, True, True, 0)
listcontainer = Gtk.Box(spacing=5)
horizontalbox.pack_start(listcontainer, False, True, 0)
listbox = Gtk.ListBox()
listbox.set_selection_mode(Gtk.SelectionMode.NONE)
listcontainer.pack_start(listbox, False, False, 5)
def amplitude_changed(event):
print(amplitude_scale.scale.get_value())
def wavelength_changed(event):
print(wavelength_scale.scale.get_value())
row = Gtk.ListBoxRow()
listcontainer = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=100)
row.add(listcontainer)
label = Gtk.Label("<b>Settings</b>", xalign=0.5)
label.set_use_markup(True)
listcontainer.pack_start(label, True, True, 0)
listbox.add(row)
class ListBox():
def __init__(self, name, lower_range, upper_range):
self.name = name
self.lower_range = lower_range
self.upper_range = upper_range
# two adjustments (initial value, min value, max value,
# step increment - press cursor keys to see!,
# page increment - click around the handle to see!,
# page size - not used here)
#self.adjustment = Gtk.Adjustment(0, 0, 20,
self.row = Gtk.ListBoxRow()
self.listcontainer = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=100)
self.row.add(self.listcontainer)
self.label = Gtk.Label(self.name, xalign=0)
self.scale = Gtk.Scale()
self.scale.set_range(self.lower_range, self.upper_range)
#self.scale.set_hexpand(True)
self.listcontainer.pack_start(self.label, False, False, 0)
self.listcontainer.pack_start(self.scale, True, True, 0)
listbox.add(self.row)
amplitude_scale = ListBox("Amplitude", 0.0, 5.0)
amplitude_scale.scale.connect("value-changed", amplitude_changed)
wavelength_scale = ListBox("Wavelength", 0.0, 20.0)
wavelength_scale.scale.connect("value-changed", wavelength_changed)
displacement_scale = ListBox("Displacement", 0.0, 10.0)
row = Gtk.ListBoxRow()
listcontainer = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=100)
row.add(listcontainer)
label = Gtk.Label("Color", xalign=0)
combo = Gtk.ComboBoxText()
combo.insert(0, "0", "Red")
combo.insert(1, "1", "Green")
combo.insert(2, "2", "Blue")
listcontainer.pack_start(label, False, False, 0)
listcontainer.pack_start(combo, True, True, 0)
listbox.add(row)
fig = Figure(figsize=(10,10), dpi=80)
ax = fig.add_subplot(111)
canvas = FigureCanvas(fig)
horizontalbox.pack_start(canvas, True, True, 0)
window.show_all()
Gtk.main()
your self.listcontainer inside ListBox class should have the property:
self.listcontainer.set_property ("homogeneous", True)
I have using tinymce text edit for my asp.net applications.Now i have added language pack.now i want to set the language pack for the text editor programatically.And also hide the language pack bar from the visible state.
for example : i want to programatically set the language of the text editior is hindi.Pleasr guide me to get out of this...
whenever user clicks translation Button in my web form , i have initialized this string variable.then i want to set the tinymce editor language programatically.
string lang="Hindi";
ptp.js
function LoadTypePad()
{
// Initialize pad
tinyMCE.init({
// General options
mode : "textareas",
theme : "advanced",
skin : "o2k7",
skin_variant : "silver",
plugins : "safari,style,table,advhr,advimage,advlink,inlinepopups,insertdatetime,preview,media,searchreplace,print,paste,fullscreen,indicime,aksharspellchecker",
// Theme options
theme_advanced_buttons1 : "newdocument,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,formatselect,fontsizeselect,fontselect,aksharspellchecker,indicime, indicimehelp",
theme_advanced_buttons2 : "selectall,cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,code,|,insertdate,inserttime,preview,|,forecolor,backcolor",
theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,media,advhr,|,print",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
theme_advanced_statusbar_location : "bottom",
theme_advanced_resizing : true,
spellchecker_rpc_url:"http://service.vishalon.net/spellchecker.aspx",
// Example content CSS (should be your site CSS)
content_css : "css/content.css",
// Drop lists for link/image/media/template dialogs
template_external_list_url : "lists/template_list.js",
external_link_list_url : "lists/link_list.js",
external_image_list_url : "lists/image_list.js",
media_external_list_url : "lists/media_list.js",
width : "100%",
init_instance_callback : "afterInit"
});
}
function showPleaseWait()
{
var mainMessage = document.getElementById("message").innerHTML;
document.getElementById("message").innerHTML = pleaseWait;
pleaseWait = mainMessage;
}
// This function finds absolute position of the element in screen and returns array.
function findPos(obj) {
var curleft = curtop = 0;
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
return [curleft,curtop];
}
}
// id= outer most id for show/hide. baseid = reference id for pointer
function showPopup(id, baseid)
{
toggle_menu(id);
var base = document.getElementById(baseid);
var l = findPos(base);
var obj = document.getElementById(id + 'content');
var im = document.getElementById(id + 'img');
var left = im.src.indexOf('left.gif') > 0;
obj.style.top = (l[1] - obj.offsetHeight - 20) + "px";
obj.style.left = (l[0] + (base.offsetWidth/2) - (left?obj.offsetWidth:0)) + "px";
l = findPos(obj);
im.style.top = (l[1] + obj.offsetHeight - 1) + "px";
im.style.left = (l[0] + (left?obj.offsetWidth - 26:0)) + "px";
}
function closePopup()
{
// hide popup
var elem = document.getElementById("step1");
elem.style.display = "none";
elem = document.getElementById("step2");
elem.style.display = "none";
elem = document.getElementById("step3");
elem.style.display = "none";
}
// Once tinymce is fully loaded
function afterInit()
{
// Find search string from referral
var term = document.referrer;
var re = /bengali|gujarati|gujrati|hindi|marathi|devnagari|devanagari|punjabi|gurmukhi|kannada|malayalam|tamil|telugu|thelugu|thamil/gi ;
var m = re.exec(term);
var result ='';
if (m != null && m.length > 0)
result = "<strong>" + m[0] + "</strong>";
else
result = "your favourite Indic Script";
// Create popup
CreatePopup("step1", "Step 1", "Click here to erase existing contents", "right");
CreatePopup("step2", "Step 2", "Select " + result + " from this dropdown list and start typing.", "left");
CreatePopup("step3", "Step 3", "Click here to get a help for typing once you selected script in Step 2", "right");
// Restore the message from please wait to spell checker
document.getElementById("message").innerHTML = "Now Akshar Spell Checker for Gujarati is available!!! Click on <img src=\"tiny_mce/plugins/aksharspellchecker/img/aksharspellchecker.gif\"> to check Gujarati spelling";
// Initialize for google search
pph = new PramukhPhoneticHandler();
pph.convertToIndicIME("q");
pph.onScriptChange("q", indicChange);
// Open up popups
showPopup("step1","elm1_newdocument");
showPopup("step2","elm1_indicime");
showPopup("step3","elm1_indicimehelp");
// Close popup after xx seconds.
setTimeout("closePopup();",15000);
}
function toggle_menu(id)
{
var elem = document.getElementById(id);
elem.style.display = elem.style.display=="none"? "":"none";
}
function CheckNewVersion()
{
var JSONRequest = tinymce.util.JSONRequest;
try {
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
} catch (e) {
// do nothing
}
JSONRequest.sendRPC({
url : "http://service.vishalon.net/pramukhtypepadmessage.aspx?v=2.5.00",
method : "",
params : "",
type: "GET",
success : function(r){
var message = r.substring(r.indexOf(",")+1);
if (message != "")
document.getElementById("message").innerHTML = "<img src='img/info.jpg' >" + message + "<br><br>";
},
error : function(e, x) {
// do nothing
}
});
}
function indicChange(id, lang)
{
var s = document.getElementById('language');
s.value = lang;
if (lang == null || lang == "")
lang = 'english';
pph.setScript(id, lang);
}
function CreatePopup(id, title,content, dir)
{
var holder = document.getElementById("plholder");
holder.innerHTML += "<div id='" +id + "' style='display:none;'>"+
"<div class='popupbody' id='" +id + "content'>" +
"<div style='float:right;'><img src='img/close.gif' style='cursor:pointer;cursor:hand;' onclick='toggle_menu(\"" + id + "\");'/></div>"+
"<div><strong>" + title + "</strong></div>"+
"<div style='clear:both'></div>"+
"<div>" + content + "</div>"+
"</div>"+
"<img src='img/" + dir + ".gif' id='" + id + "img' style='position:absolute;'/>"+
"</div>";
}
var pph, pleaseWait = "Please wait while Pramukh Type Pad is loading... <img src='img/progress.gif' /> (Loading problem??? Get Simple Pramukh Type Pad )";
You have to download your language pack and unzip it.
Then you have to put every single js file in the corresponding folder of your tinymce folder.
You have to specify the language as well.
If you're using TinyMCE - jQuery Plugin you have to do something like this:
// Initializes all textareas with the tinymce class
$(document).ready(function() {
$('textarea.tinymce').tinymce({
script_url : '../js/tinymce/jscripts/tiny_mce/tiny_mce.js',
theme : "advanced",
language: "hi",
...
});
});
If you want to remove tinyMCE (and I guess you have to do it if you want to reset the language) from your text-area you can use this code:
tinyMCE.execCommand('mceRemoveControl', false, 'mycontrol_id');
as specified here.
and you can recreate it using the same code.
You can wrap everything in a function and pass the language parameter:
function setup(language) {
tinyMCE.init({
mode : "textareas",
theme : "advanced",
language: language,
plugins : "pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template",
theme_advanced_buttons1 : "save,newdocument,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect,fontselect,fontsizeselect",
theme_advanced_buttons2 : "cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor",
theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,charmap,emotions,iespell,media,advhr,|,print,|,ltr,rtl,|,fullscreen",
theme_advanced_buttons4 : "insertlayer,moveforward,movebackward,absolute,|,styleprops,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,pagebreak",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
theme_advanced_statusbar_location : "bottom",
theme_advanced_resizing : true
});
}
If you want to remove buttons from the toolbar you have to work on these lines:
theme_advanced_buttons1
theme_advanced_buttons2
...
removing those you don't need.
There's a list of all buttons and plugins here.
If you want to add your own buttons you can find a sample here.
UPDATE:
Since you've used your own plugin, I guess you have defined it in the plugin section:
tinyMCE.init({
mode : "textareas",
theme : "advanced",
language: 'hi',
plugins : "myPlugin, pagebreak ... ",
theme_advanced_buttons1 : "save,newdocument,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect,fontselect,fontsizeselect",
theme_advanced_buttons2 : "myPlugin",
...
});
If you don't want to show it, just remove it from the theme_advanced_buttons2.