I have an dialog window with Gtk::TreeView. This dialod shows main filesystem tree
and provides option to select folders on the disk. When user selects some folder, I am
adding an Gtk::Stock image to the row that represents that folder.
To do this, I have created an Gtk::CellRendererPixbuf associated with the last column of my tree:
//appending columns
directory_tree.append_column("Folder List", dir_columns.name);
Gtk::TreeViewColumn *column = directory_tree.get_column(0);
if(column) column->set_expand(true);
Gtk::CellRendererPixbuf *cell = Gtk::manage(new Gtk::CellRendererPixbuf);
directory_tree.append_column("", *cell);
column = directory_tree.get_column(1);
if(column) column->add_attribute(cell->property_stock_id(), dir_columns.stock_id);
Link to this bit of code: https://github.com/mc-suchecki/Imagine/blob/master/gui/dialogs.cpp#L47
Gtk::CellRendererPixbuf 'translates' Gtk::StockId found in 'dir_columns.stock_id'
to an image located in tree. When I add image to row like this:
//selecting folder
(*folder)[fs_columns.stock_id] = Gtk::StockID(Gtk::Stock::FIND).get_string();
(*folder)[fs_columns.included] = true;
everything is ok, but when I try to delete the image this way:
//unselecting folder
(*folder)[fs_columns.stock_id] = "";
(*folder)[fs_columns.included] = false;
the image correctly disappears, but there are some errors in command line like this (this is not the exact message, I will post it when I will be able to launch my application):
(imagine:9376): Gtk-WARNING **: Gtk StockId not found
Of course the reason of the warning is obvious (there is no StockId item associated with blank name), however my question is: Is there a way to delete an image from Gtk::TreeView row which would not generate any Gtk warnings?
Code where i deselect folder is here:
https://github.com/mc-suchecki/Imagine/blob/master/core/core.cpp#L207
Thank you very much in advance and sorry for my English.
Change the visible property to false if you want to get rid of the image, instead of the stock-id property.
Related
I'm very new to Oracle Apex and currently I want to use and customize Gantt charts. What I want to achieve it to show line breaks in the row-labels. Currently every newline character gets cut out and I am not sure where this happens and how I can prevent this.
The marked text contains newline characters. Don't be confused by the <br>, I just tests if this does the trick.
I just want to show more some information in the for each row. If there is another more elegant way, it would be very nice to give a tip.
Update:
I did some research and found a very nice example on a similar topic, in this case to create a custom tooltip https://youtu.be/2rZAIR_0tNg?t=2532.
I wanted to do the same thing for the row_axis label renderer, but nothing gets visualized.
The render function I use:
function custom_row_axis_label_renderer(data_context){
var row_axis_label_elem = document.createElement("g");
$("row_axis_label_elem").addClass("custom_row_axis_label");
row_axis_label_elem.innerHTML = '<text font-size="14px">Hello World</text>';
console.log(row_axis_label_elem);
return row_axis_label_elem;
}
The rendered element kind of exists, but it's get the size 0x0 from somewhere.
Am I missing something here?
Regards,
Nik
Meanwhile I found the solution on how to build a custom renderer. The main part I didn't new is that you NEED to pass x and y coordinates to have the new label to be rendered correctly. I found a proper example the the oracle forum, but unfortunately I can't find the link anymore to give credit to the original example.
Here is my code. It creates two text elements below each other to achieve a mocked line break and it adds a yellow icon. Of course you can use the data_context object to access the actual label. Add this part in the "Function and Global Variable Declaration
" part of your page:
custom_row_axis_label_renderer = function (data_context){
var row_axis_label_elem = document.createElementNS("http://www.w3.org/2000/svg", "g");
var upper_text = document.createElementNS("http://www.w3.org/2000/svg", "text");
var lower_text = document.createElementNS("http://www.w3.org/2000/svg", "text");
var icon_node = document.createElementNS("http://www.w3.org/2000/svg", "circle");
upper_text.textContent = "Hello";
upper_text.setAttribute("dominant-baseline","text-before-edge");
upper_text.setAttribute("class","oj-gantt-row-label");
upper_text.setAttribute("font-size","14px");
upper_text.setAttribute("text-anchor","end");
upper_text.setAttribute("x","220");
upper_text.setAttribute("y","5");
lower_text.textContent = "World";
lower_text.setAttribute("dominant-baseline","text-before-edge");
lower_text.setAttribute("class","oj-gantt-row-label");
lower_text.setAttribute("font-size","14px");
lower_text.setAttribute("text-anchor","end");
lower_text.setAttribute("x","220");
lower_text.setAttribute("y","25");
icon_node.setAttribute("cx","240");
icon_node.setAttribute("cy","25");
icon_node.setAttribute("r","8");
icon_node.setAttribute("class","u-color-7");
row_axis_label_elem.appendChild(upper_text);
row_axis_label_elem.appendChild(lower_text);
row_axis_label_elem.appendChild(icon_node);
return row_axis_label_elem;
}
Also you need to set the renderer of the row-axis-label. I also made the rows and task a little bit bigger to have enough space for two lines of text in the label. Add this in the "JavaScript Initialization Code" in the attriutes of you chart:
function( options ){
options.rowAxis.label = {renderer : custom_row_axis_label_renderer};
options.rowDefaults = {height : 60};
options.taskDefaults = {height: 40};
return options;
}
I'm creating a menu in gaffer that populate automatically from a string list called "shotlist"
the idea is to have a custom menu for each entry of the list and have an action relative to each entry too, like :
click on sh001 = sh001
click on sh002 = sh002
click on sh003 = sh003
my problem is that my code return :
click on sh001 = sh003
click on sh002 = sh003
click on sh003 = sh003
I understand that when I click on a button, it always return the 3rd value of "shotlist", as it's the last one than the loop worked on, but I dont understand how to set the loop differently to have the right result
actually my code is :
def shotSelection( menu ):
shotVar=str(shotName)
print shotName
scriptWindow = menu.ancestor( GafferUI.ScriptWindow )
root = scriptWindow.scriptNode()
root["variables"]["projectshot"]["value"].setValue( shotVar )
root=application.root()
shotlist=["sh001","sh002","sh003"]
for shotName in shotlist:
GafferUI.ScriptWindow.menuDefinition(application).append("/Pipeline/ShotSwitcher/{0}".format(shotName), { "command" : shotSelection } )
I have also tried with the method described here but i dont understand well enough how it's work to apply it to my script.
the menu creation part from gaffer works well. but I dont found a way to set up my menu from the list and have the right action on it at the same time
thank you
EDIT:
actually I found the problem but not sure how to fix it
GafferUI.ScriptWindow.menuDefinition(application).append("/Pipeline/ShotSwitcher/{0}".format(shotName), { "command" : shotSelection }
shotSelection does not transmit any info of the shot clicked on
i fixed my issue with functools(), allowing to transmit the value in each loop
Update 2:
I am still fighting to get the Icon save on the server.
Here what I am doing:
Item item = Sitecore.Context.Database.GetItem(imageId);
var imageIconUrl = Sitecore.Resources.Images.GetThemedImageSource(item.Appearance.Icon, ImageDimension.id32x32);
if (!string.IsNullOrEmpty(imageIconUrl))
{
// download the icon from the url
var iconFullPath = "e:\\pngIcons\\excelIcon.png";
var webClient = new System.Net.WebClient();
var downloadPath = "http://serverName/" + imageIconUrl;
webClient.DownloadFile(downloadPath, iconFullPath);
}
The variable downloadPath contains following string:
http://serverName/sitecore/shell/themes/standard/~/media/E503BA48C89B422D8400393F1C7086A7.ashx?h=32&thn=1&w=32&db=master
At the end what I can see is a png file but there is nothing in it. I also copy the string I get in variable downloadPath and pasted it in browser and I can see the Icon as follow:
Please let me know what I am doing wrong. Or How I can save the Icon. Thanks!!
Original Question:
The sitecore media item has a field "Media". I am talking about this:
I want to access this field. And the reason is:
If I access it with e.g. item.GetMediaStream() then I will get the complete file. I just want to save this little icon some how on the server. Is it possible ?
To get the icon/thumbnail you can use
var icon = Sitecore.Resources.Media.MediaManager.GetThumbnailUrl(mediaItem);
To get the url of the thumbnail.
If you want the stream of the thumbnail you need to use the MediaData object. Like this:
var mediaItem = new MediaItem(item)
var mediaData = new MediaData(mediaItem);
var iconStream = mediaData.GetThumbnailStream();
if (iconStream.Length < 0)
{
// The stream is empty, its probably a file that Sitecore can't
// generate a thumbnail for. Just use the Icon
var icon = item.Appearance.Icon;
}
This will get the icon or thumbnail of the actual media blob that is attached to the media item. If you just want the icon of the Sitecore item, then use Martins method.
If the stream is empty, then Sitecore can't generate a thumbnail for it, so you can just use the icon file for the media item template. item.Appearance.Icon
Appearance section (of Standard Template) has a field called Icon - this is where you can modify icon for the item. There is also a field called Thumbnail - your excel icon is sitting there
You can access the field programmatically, just mind that it starts with two underscores: __Icon:
var iconField = item.Fields["__Icon"];
var thumbnailField = item.Fields["__Thumbnail"];
Update: As you asked, below is the code that saves either of fields into the file on a drive. I have tested the code and confirm successfully stores icon from thumbnail field into the file:
string mediaItemPath = "/sitecore/media library/Files/ExcelFile";
string mediaFiedlName = "Thumbnail"; // also can be "__Icon"
var item = Sitecore.Context.Database.GetItem(mediaItemPath);
var iconField = item.Fields[mediaFiedlName];
if (iconField.HasBlobStream)
{
var thumb = (ImageField)iconField;
var bl = ((MediaItem)thumb.MediaItem).InnerItem.Fields["blob"];
Stream stream = bl.GetBlobStream();
byte[] buffer = new byte[8192];
using (FileStream fs = File.Create("D:\\you_file_name.ico")) // change your path
{
int length;
do
{
length = stream.Read(buffer, 0, buffer.Length);
fs.Write(buffer, 0, length);
}
while (length > 0);
fs.Flush();
fs.Close();
}
}
Update 2: If that does not help then I would advise to look around the way how that icon gets generated on Media field in Sitecore. In the worst case you may do the following - right click that icon and see its url. You will have something similar to what I assign to variable below:
string url = "http://test81/sitecore/shell/Applications/-/media/B4F61650CBE84EE396649602C0C48E1B.ashx?bc=White&db=master&h=128&la=en&mw=640&thn=1&vs=1&ts=b8046903-ae57-4f9d-9dd5-b626ee5eee90";
Of course your URL should have your hostname and media prefix and the rest of parameters. Then use Webclient with that modified URL:
WebClient webClient = new WebClient();
webClient.DownloadFile(url, "e:\\you_file_name.ico");
Not ideal, but may work. Note, that the code above should work in a context of already logged user, so you need to authorise you Webclient prior that (many articles on S.O. how to do that).
Please reply if that approach has worked for you (I've spent decent time writing and testing that code in debugger, so would want to know whether that helped)
I have written a Tkinter program in which the Browse button is used to select a file and the selected file's complete path gets displayed in the Entry widget. But my problem is, it's displaying the path with 'forward'(/) slashes instead of the conventional windows format of 'backward'(\) slashes. This is strange for me since I'm working on windows os.
Why this occurs ? Is there any before hand fix for this, instead of replace string option ?
my code:
def selectfile():
fileName = askopenfilename(parent=root, title='Choose a file', initialdir='C:\\')
custName.set(fileName) #Populate the text field with the selected file
#create the 'filepath' field
custName = StringVar(None)
filepath = Entry(root, width ='50', textvariable=custName).pack(anchor=W)
#Create the 'Browse' button
browseButton = Button(root, text="Browse", relief = 'raised', width=8, command=selectfile, cursor='hand2').place(x=325,y=16)
Expected Output in Entry widget:
c:\data\file.txt
Actual Output in Entry widget:
c:/data/file.txt
You can always use replace() to replace "/" with "\" for string. Here's link with docs about replace() method:
https://docs.python.org/2/library/string.html?highlight=replace#string.replace
This is workaround fix. Try looking more deeply inside Tkinter's docs for actual answer why this occurs.
I am writing simple GUI software using wxWidgets 3.0 in CodeBlocks 13.12, on Win 7 x64 machine.
I would like to create a menu for the frame, and each item in the frame should make a different text appear in the status bar when highlighted. Below is what I have done so far ( only the menu part of code ). Menu and status bar appear as planned. The problem is that every item ( in File and Data sub menus ) when highlighted displays "Save project" in the status bar - which is the very first item in the first sub menu. How to change this so that proper menu item names are displayed ?
CODE :
wxMenuBar* mbar = new wxMenuBar();
wxMenu* fileMenu = new wxMenu(_T(""));
//fileMenu->Append(, _("&"), _("")));
fileMenu->Append(SaveProject, _("&Save project"), _("Save project"));
fileMenu->Append(SaveProjectAs, _("&Save project as"), _("Save project as"));
fileMenu->Append(OpenNewProject, _("&Open new project"), _("Open new project"));
fileMenu->Append(OpenExistingProject, _("&Open existing project"), _("Open existing project"));
fileMenu->AppendSeparator();
fileMenu->Append(Quit, _("&Quit"), _("Quit"));
mbar->Append(fileMenu, _("&File"));
wxMenu* dataMenu = new wxMenu(_T(""));
//fileMenu->Append(, _("&"), _("")));
dataMenu->Append(ImportData, _("&Import data"), _("Import data"));
dataMenu->Append(ExportData, _("&Export data"), _("Export data"));
dataMenu->Append(SavaDataAs, _("&Save data as"), _("Save data as"));
mbar->Append(dataMenu, _("&Data"));
mainFrame->SetMenuBar(mbar);
I suspect the problem is due to your use of duplicate menu IDs (e.g. SaveProject is used twice). While it's not clear why should this result in the observed behaviour, it is pretty clear that you cannot reuse the menu IDs as you will have no way of distinguishing between the events generated by the two items with the same ID. So don't do this.