I want to disable make a copy option when user do right click on documents in m-files, until no body cant copy documents to other class to use,
is there anybody to help me to solve it?
You can achieve this with M-Files User Interface Extensibility Framework.
The needed function is shellFrame.Commands.SetCommandState(9, CommandLocation_All, 3).
1st parameter is command ID (list of built-in command IDs, 9 is BuiltinCommand_MakeCopy)
2nd parameter defines the parts of the UI where you want to set the new command state
3rd parameter defines the new state (3 is CommandState_Hidden)
You will need to set up the UI extension with some configuration files but there is a sample that comes close to your use-case: Alter Context Menu Depending on SelectedObject. The code to hide the context menu option in main.js would be:
"use strict";
function OnNewShellUI(shellUI) {
shellUI.Events.Register(
Event_NewNormalShellFrame,
handleNewNormalShellFrame);
}
function handleNewNormalShellFrame(shellFrame) {
shellFrame.Events.Register(
Event_Started,
getShellFrameStartedHandler(shellFrame));
}
function getShellFrameStartedHandler(shellFrame) {
return function () {
shellFrame.Commands.SetCommandState(9, CommandLocation_All, 3);
};
}
Related
I have created cascading dropdown. I need to load dropdown based on parent dropdown selection. I am trying to use onpropertychange event. but I am getting error on super.onpropertychange saying {Property 'onPropertyChange' does not exist on type 'BaseClientSideWebPart'.}
please let us know what I havve missed.
protected onPropertyChange(propertyPath: string, newValue: any):void{
if(propertyPath === "listDropDown"){
// Change only when drop down changes
super.onPropertyChange(propertyPath,newValue);
// Clears the existing data
this.properties.ItemsDropDown = undefined;
this.onPropertyChange('ItemsDropDown', this.properties.ItemsDropDown);
// Get/Load new items data
this.GetItems();
}
else {
// Render the property field
super.onPropertyChange(propertyPath, newValue);
}
}
Instead of onPropertyChange, perhaps you mean onPropertyFieldChanged from the BaseWebPart class?
The error message is accurate - web parts don't have a method called onPropertyChange. The above sounds like the closest match for what you are trying to do. Note that it takes not two arguments, but three: propertyPath, oldValue, and newValue.
I'm planning on having multiple ace editor instances on a page and I'd like to know if the core libraries are keeping track of them so I can easily get a reference to them later.
If not, would keeping the editor instances in a dictionary or object be a good way to do it? Could I create an object on the ace class and should they be by reference or id?
var editor1 = ace.edit("myEditorDivID");
var editor2 = ace.edit("myEditorDivID2");
var editors = ace.editors;
console(editor1==editors["myEditorDivID"]); // true
console.log(editors["myEditorDivID"]); // editor1
var editorIds = ace.editorIds;
console.log(editorIds[0]); // myEditorDivID
And is there an ace destroy method that should be used to remove references to these instances?
Nevermind on part two of this question. I just found the destroy methods:
editor.destroy();
editor.container.remove();
Update:
I just thought of something else. If we can keep track of the id's or references we can prevent same id collisions. It can also help track how many editors are on a page or if multiple are being created by accident.
I just looked at the ace source and don't see anything keeping track of the editors as they are created. Should I try to whip something up or let someone else tackle it?
Update 2:
I'm thinking to add an editors property and set it by id. I've added an answer with a suggestion.
Answering my own question, no, it does not. But I suggest the following Pseudo code:
ace.addEditorById = function (id, editor) {
if (ace.editors[id]!=null) throw Error ("Editor already created");
ace.editors[id] = editor;
}
ace.getEditorById = function (id) {
return ace.editors[id];
}
ace.removeEditorById = function (id) {
var editor = ace.editors[id];
if (editor) {
editor.destroy();
editor.container.remove();
delete ace.editors[id];
}
}
ace.editors = {};
// then when I create an editor I use the following code:
editor = ace.edit("editor1");
ace.addEditorById(editor);
editor2 = ace.edit("editor2");
ace.addEditorById(editor2);
Maybe the editor can be added in the edit call. What do you think?
With Firefox 17.0.1 I am using an add-on called KeyConfig 20110522 to set some new hot keys and also set the acceltext of menuitems for my new keys as well as for add-ons that do not bother to do so.
I want the acceltext of the menuitems to be set when Firefox starts, but currently I am just using a hot key to execute the following code against the UI via KeyConfig:
document.getElementById("tabmix-menu")
.setAttribute("acceltext","Alt+Ctrl+Shift+T");
// more of the same...
I need a couple of beginners tips:
How can I execute arbitrary code against the UI in the same way as I execute against an HTML page via the console?
Is there a sneaky way to get a clump of code to execute on browser start-up without delving into XUL development?
Is there a way to trace commands executed against the UI so I can get at command calls instead of using triggers when I set my hot keys like so:
document.getElementById("tabmix-menu").click();
Any other tips on this type of low-level hacking would also be welcome.
You can execute arbitrary code against the Firefox UI from an addon, but as you say, doing all the XUL related stuff is a bit boring :-)
Enter "Bootstrapped" extensions!
Part 1:
A "Bootstrapped" (or re-startless) extension needs only an install.rdf file to identify the addon, and a bootstrap.js file to implement the bootstrap interface.
Bootstrapped Extension: https://developer.mozilla.org/en-US/docs/Extensions/Bootstrapped_extensions
Good example: http://blog.fpmurphy.com/2011/02/firefox-4-restartless-add-ons.html
The bootstrap interface can be implemented very simply:
function install() {}
function uninstall() {}
function shutdown(data, reason) {}
function startup(data, reason) { /* YOUR ARBITRARY CODE HERE! */ }
You compile the extension by putting install.rdf and bootstrap.js into the top-level of a new zip file, and rename the zip file extension to .xpi.
Part 2:
Your code is privileged and can use any of the Mozilla platform APIs. There is however an issue of timing. The moment-in-time at which the "startup" function is executed is one at which no Chrome window objects exist yet!
If it's important for your code that you have a Chrome Window, we need to wait for it to appear:
// useful services.
Cu.import("resource://gre/modules/Services.jsm");
var loader = Cc["#mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader);
var wmSvc = Cc["#mozilla.org/appshell/window-mediator;1"]
.getService(Ci.nsIWindowMediator);
var logSvc = Cc["#mozilla.org/consoleservice;1"]
.getService(Ci.nsIConsoleService);
// get the first gBrowser
var done_startup = 0;
var windowListener;
function do_startup(win) {
if (done_startup) return;
done_startup = 1;
wmSvc.removeListener(windowListener);
var browserEnum = wmSvc.getEnumerator("navigator:browser");
var browserWin = browserEnum.getNext();
var tabbrowser = browserWin.gBrowser;
/* your code goes here! */
}
// window listener implementation
windowListener = {
onWindowTitleChange: function(aWindow, aTitle) {},
onCloseWindow: function(aWindow) {},
onOpenWindow: function(aWindow) {
var win = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
win.addEventListener("load", function(aEvent) {
win.removeEventListener("load", arguments.callee, false);
if (aEvent.originalTarget.nodeName != "#document") return;
do_startup();
}
};
// CODE ENTRY POINT (put this in bootstrap "startup" function)
wmSvc.addListener(windowListener);
in my test application, the ModuleCatalog is populated from the specified directory with all my modules in it. What I'd like to do is to add the name of all these moudles to a Menu as menuitems, e.g. if I have 3 modules in the directory, the menu will show 3 menuitems with the name of modules.
I thought I can get the list of ModuleInfo like below. But miList shows 0 count. What is the problem here?
protected override void ConfigureModuleCatalog()
{
DirectoryModuleCatalog directoryCatalog = new DirectoryModuleCatalog()
{ ModulePath = #".\Modules" };
((AggregateModuleCatalog)ModuleCatalog).AddCatalog(directoryCatalog);
List<ModuleInfo> miList = ModuleCatalog.Modules.ToList() ; // returns 0 items ??
}
The list of the modules will be populated after InitializeModules has run later on during the bootstrapping process. InitializeModules calls ModuleManager.Run().
You could populate your menu in your shell after it has loaded (get ahold of the ModuleCatalog through the ServiceLocator.Current) You could also populate your menu in the OnPopup event.
I am getting up to speed on Composite WPF, building a small demo app to work through the issues. My app has one region, and two modules, Module A and Module B. Each module contains a simple "Hello World" text block. Both modules are set up as load-on-demand, as per this MSDN How-To.
The shell has two buttons, "Load Module A" and "Load Module B". When a button is clicked, the corresponding module is loaded. So, lets say I click "Load Module A", then "Load Module B". Module A, then Module B load as expected. But if I click "Load Module A" again, nothing happens.
I'm stuck at this point. I think my problem is that I need to activate and deactivate the views in the modules, rather than using load-on-demand. But I have no idea how to do that, and I can't find any documentation or blogs that talk about it.
So, here's my question: How to I load/unload (or show/hide) views? If someone can point me to sample code, I'd really appreciate it. Thanks for your help.
I found my answer. Here is the approach: Load all the modules at startup, then activate and deactivate views as you need them. I am going to write this issue up as a CodeProject article, but here is an outline of how to do it:
(1) In the module Initialize() method, add the module, but don't activate it:
public void Initialize()
{
// Get main region
var mainRegion = m_RegionManager.Regions["MainRegion"];
// Load Module B
var newView = new ModuleBView();
mainRegion.Add(newView, "ModuleA.ModuleAView");
}
Note that the Add() method has two parameters. The second parameter is the name of the view, which we set to the value produced by the ToString() method of the view. We'll see why in the next step.
(2) When activating a view, we need to deactivate the previous view. But we may not know the name of the view, so we deactivate all active views:
public static void ClearRegion(IRegion region)
{
// Get existing view names
var oldViewNames = new List<string>();
foreach (var v in region.Views)
{
var s = v.ToString();
oldViewNames.Add(s);
}
// Remove existing views
foreach (var oldViewName in oldViewNames)
{
var oldView = region.GetView(oldViewName);
region.Deactivate(oldView);
}
}
Since we set the name of each view equal to its ToString() value, we can get the names easily without knowing anything about them in advance.
(3) Now we activate the new view. I do it in an MVVM ICommand.Execute() method:
public void Execute(object parameter)
{
// Get main region
var mainRegion = m_ViewModel.RegionManager.Regions["MainRegion"];
// Clear region
ModuleServices.ClearRegion(mainRegion);
// Activate Module A view
var moduleAView = mainRegion.GetView("ModuleA.ModuleAView");
mainRegion.Activate(moduleAView);
}
Hopefully, that will be enough to get you going. Like I said, I plan to do a more complete writeup, with demo code, for CodeProject.
David Veeneman
Foresight Systems