How to set the default directory in Komodo from an an extension? - komodo

I'm working on a KomodoIDE/KomodoEdit extension that creates a new file and then opens it in a new editing tab using
...
var obsvc = Components.classes["#mozilla.org/observer-service;1"].
getService(Components.interfaces.nsIObserverService);
...
Display.initWithPath(Target.path);
Display.append(what);
try {
obsvc.notifyObservers(null, 'open-url', "file://" + Display.path);
} catch (e) {
alert(e);
}
which works, but I would also like it to set Komodo's default directory to the same directory where this file lives, but I don't see a way to do that automatically.
I found the doCommand...
ko.commands.doCommand('cmd_openDirectory')
but this just launches a file dialog that asks the user to pick a directory. I'd like to do something to set it programatically using something like...
obsvc.notifyObservers(null, 'open-directory', "file://" + Display.path);
(which I know doesn't work but is sort of the idea).

I just discovered that the ko.places.manager object has a function to set the default Places window-pane directory. Below is an example of how I used it. The uri should be set to the full directory path and, in the case of Windows, backslashes should get escaped...
function SetPlace(ko, uri) {
try {
ko.places.manager.openDirURI("file:///" + uri.replace(/\\/g, "\\\\") );
} catch(e) {
alert("Could not set place to: " + uri.replace(/\\/g, "\\\\") + "\n" + e);
}
}

The nsIFile interface provides this:
// Get current working directory
var file = Components.classes["#mozilla.org/file/directory_service;1"].
getService(Components.interfaces.nsIProperties).
get("CurProcD", Components.interfaces.nsIFile);
The Komodo preferences service would also be an option:
var gprefs = Components.classes["#activestate.com/koPrefService;1"].
getService(Components.interfaces.koIPrefService).prefs;
gprefs.setStringPref("mruDirectory", "Display.path);
References
How do I get the path of the project folder
Getting Special Files
Komodo JS Macro - insert a relative path from the current editor file
mruDirectory
XPCOM API Reference
Komodo Profile Structure
Where does Komodo Store File Preferences
Getting/Setting a Komodo Preference

Related

Creating VSIX package for TFS Source control explorer context menu extension

I am trying to create VSIX package to extend functionality of TFS 2012 source control right click context menu when clicking on branch.
I don't want to use Add-in. this has to be package which other developers can directly install.
The customized menu items need to appear in the source control explorer contextual menu after they install the extension. I am not able to get any sample for this requirement or not able to get proper documentation source. One of sample I found is "TFS community branch tool", which is kind of similar functionality I am looking for, but I am not able to get the source code of it.
Appreciate your help.
I assume that you are familiar with the .vsct file, command/menu/groups Guids/Id stuff (all this is documented in MSDN). So, the question would be which is the Guid/Id of the group inside the context menu of Source Control Explorer.
Guessing that you may want your command below the "Get Latest Version" menu entry of the context menu of a file, the code would be:
<Commands package="guidVSMyPackagePkg">
<Buttons>
<Button guid="guidVSMyPackageCmdSet" id="cmdidMyCommand" priority="0x0100" type="Button">
<Parent guid="guidSourceControlExplorerMenuGroup" id="SourceControlExplorerMenuGroupId"/>
<Strings>
<ButtonText>My Command</ButtonText>
</Strings>
</Button>
</Buttons>
</Commands>
<Symbols>
<GuidSymbol name="guidVSMyPackagePkg" value="{...}" />
<GuidSymbol name="guidVSMyPackageCmdSet" value="{...}">
<IDSymbol name="cmdidMyCommand" value="0x0100" />
</GuidSymbol>
<GuidSymbol name="guidSourceControlExplorerMenuGroup" value="{ffe1131c-8ea1-4d05-9728-34ad4611bda9}">
<IDSymbol name="SourceControlExplorerMenuGroupId" value="0x1111" />
</GuidSymbol>
</Symbols>
Building upon Carlos Quintero's answer:
If you need to put the command in any other location in the Source Control Explorers context menu, you need the right Id. Using EnableVSIPLogging you can only find information for commands and their parent menus, but not the groups.
In order to find Group Ids (or any other ID for that matter) used in the Source Control Explorer you can follow these steps (for VS2015):
Decompile Microsoft.VisualStudio.TeamFoundation.VersionControl.dll (using JetBrains dotPeek for instance).
Open Resources\HatPackage.resources.
Look up 1000.ctmenu and copy the Base64 data.
Convert the data from Base64 to bytes.
Save the bytes in a file as TfsMenu.cto (the extension needs to be .cto and it needs to be in a location with write rights for the next step to work).
Run "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VSSDK\VisualStudioIntegration\Tools\Bin\vsct.exe" TfsMenu.cto TfsMenu.vsct to decompile the file.
Now you have the original .vsct file that was used to make the TFS plugin. In here you can look up all IDs.
To get you started finding the menuitems in TfsMenu.vsct, you can enable EnableVSIPLogging:
Add HKEY_CURRENT_USER\SOFTWARE\Microsoft\VisualStudio\14.0\General\EnableVSIPLogging as DWORD32 with value 1.
Now, in Visual Studio, when Holding Ctrl+Shift while hovering menus or clicking menu items in the Source Control Explorer, a messagebox pops up with information about that item, including the GUID and ID of that menu/menuitem
#Erik I was so happy to run across your explanation for extracting the vsct as I trying very hard to figure out how to do that very thing. Just to expound upon your answer I converted it into code. Sharing here in case anyone is interested.
static void Main(string[] args)
{
/*
Extract menus from extensions
http://stackoverflow.com/questions/29831181/creating-vsix-package-for-tfs-source-control-explorer-context-menu-extension
*/
try
{
string vsctPath = ConfigurationManager.AppSettings["VSCTPath"];
if (!File.Exists(vsctPath))
{
WriteConsole("The path to the vsct.exe could not be found. Please edit the app.config to set the right executable path.", ConsoleColor.Yellow);
return;
}
//TODO: Convert to a command line argument
string dllPath = #"C:\Program Files (x86)\Microsoft SQL Server\130\Tools\Binn\ManagementStudio\Extensions\Application\Microsoft.SqlServer.Management.SqlStudio.Explorer.dll";
var assembly = Assembly.LoadFrom(dllPath);
if (assembly == null)
{
WriteConsole("Could not load assembly.", ConsoleColor.Yellow);
return;
}
var resourceName = assembly.GetManifestResourceNames().FirstOrDefault(n => Regex.IsMatch(n, #"VSPackage\.resources", RegexOptions.IgnoreCase));
if (String.IsNullOrWhiteSpace(resourceName))
{
WriteConsole("Could find VSPackage.resources in assembly.", ConsoleColor.Yellow);
return;
}
var resourceManager = new ResourceManager(Path.GetFileNameWithoutExtension(resourceName), assembly);
if (resourceManager == null)
{
WriteConsole("Could find load the resource " + resourceName + ".", ConsoleColor.Yellow);
return;
}
var menus = resourceManager.GetObject("Menus.ctmenu") as byte[];
if (menus == null)
{
WriteConsole("Could find Menus.ctmenu resource in VSPackage.resources.", ConsoleColor.Yellow);
return;
}
string dir = Path.Combine(Path.GetTempPath(), "PackageMenus");
string fileName = Path.GetFileNameWithoutExtension(dllPath) + ".cto";
Directory.CreateDirectory(dir);
Directory.SetCurrentDirectory(dir);
File.WriteAllBytes(Path.Combine(dir, fileName), menus);
string processArgs = String.Format(#"{0} {1}.vsct", fileName, fileName);
var pi = new ProcessStartInfo(vsctPath, processArgs);
pi.UseShellExecute = false;
pi.RedirectStandardError = true;
pi.RedirectStandardOutput = true;
var ret = Process.Start(pi);
var output = ret.StandardOutput.ReadToEnd();
var errors = ret.StandardError.ReadToEnd();
Console.WriteLine(output);
if (!string.IsNullOrWhiteSpace(errors))
{
Console.Write("Errors: ");
WriteConsole(errors, ConsoleColor.Red);
}
else
{
Console.WriteLine("New files written to: " + dir);
}
}
catch(Exception ex)
{
WriteConsole(ex.ToString(), ConsoleColor.Red);
}
finally
{
Console.WriteLine("\r\nPress any key to continue.");
Console.ReadKey(true);
}
}
private static void WriteConsole(string message, ConsoleColor color = ConsoleColor.White)
{
Console.ForegroundColor = color;
Console.WriteLine(message);
Console.ResetColor();
}

Allow all file types to be selected in Extendscript's File object openDlg() method on MacOS

I am trying to get a reference to a File object using the File.openDlg() method using Extendscript, but when I do this it only seems to allow me to select a specific file type. I want the dialog to allow me to open any type of file. When I use File.openDialog() I am able to select any file type, but because I am launching the OS specific file chooser when a modal dialog button is clicked, it causes the open file chooser to keep popping up--I don't know why it keeps looping, but I suspect it has to do with the "modalness" of the dialog that is currently up when the method is called. So, I am left with simply using the File.openDlg() method, but I don't understand how to inform the MacOS to allow a user to select any file type.
In Adobe's documentation the signature for the .openDlg method is as follows:
fileObj.OpenDlg ([prompt][,filter][,multiSelect])
Then it specifies that the [filter] paramter is:
In Mac OS, a filter function that takes a File instance and returns true if the file
should be included in the display, false if it should not.
So, because I do not want any filetype masking I call the method like so:
newFootageSrc.openDlg("Select your file", function(file) {return true;}, false);
This doesn't work, so I found older Adobe documentation where this was specified for the [filter] param:
In Mac OS, a string containing the name of a function defined in the current
JavaScript scope that takes a File object argument. The function is called
foreach file about to be displayed in the dialog, and the file is displayed
only whenthe function returns true
So, I simply made a named function like this
function allFileTypesOSX(file){ return true; }
And then referenced allFileTypesOSX in the method call like this:
newFootageSrc.openDlg("Select your file", "allFileTypesOSX", false);
That didn't work, so I thought maybe just passing in the identifier itself rather than string would do the trick:
newFootageSrc.openDlg("Select your file", allFileTypesOSX, false);
But alas, that didn't work. Has anybody successfully been able to control file types in the MacOS dialog using ExtendScript?
I know I have this working in scripts at home, so I'll double check the syntax I use when I get home, but I do something along these lines (I'm supporting both windows and mac users).
var fileMask;
if(isWindows()) fileMask = '*.psd';
if(isMac()) fileMask = function(file){file.name.match(/\.psd$/i) ? true:false;}
var files = File.openDialog ('prompt', fileMask, true);
Its more similar to original attempt - you should be passing the actual filter function, not its name.
ETA: If you're not trying to actually limit the selectable files - have you tried just passing null, or leaving the parameter out altogether? They are all optional.
ETA: actual code from a working script (for Photoshop, works in CS3+). By 'works' I mean users on macs are able to select the files they need. I don't have a mac myself to actually see what they see. In a different script I found the following comment to myself above the isSupported function: 'returns true or false depending on if file is a png. 'Filter' doesn't seem to be working right on macs so this is a double check'. If the filter function isn't working as per the documentation this will definately be a problem for you when using the openDlg version of the method.
var filter;
if (isWindows()) {
filter = ["PNG:*.png"];
}
else {
filter = isSupported;
}
win.btnAdd.onClick = function() {
var f = File.openDialog("Open File", filter, false) ;
if (f == undefined)
return;
if (isSupported(f)) {
files = new Array();
files[0]=f;
win.lstImages.text = f.name;
methodInvoker.EnableControls();
} else {
alert("'" + decodeURI(f.name) + "' is an unsupported file.");
}
};
isSupported = function(file) {
try {
//macs will send a file or a folder through here. we need to respond true to folder to allow users to navigate through their directory structure
if (file instanceof Folder)
return true;
else
return file.name.match(/\.png$/i) != null;
} catch (e) {
alert("Error in isSupported method: " + e);
}
}

How to restore selected path in FolderBrowserDialog

In my application i just want to restore the path which was selected previously..
using (FolderBrowserDialog dlgDirestorySelector = new FolderBrowserDialog())
{
string directoryName;
dlgDirestorySelector.ShowNewFolderButton = false;
if (dlgDirestorySelector.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
directoryName = dlgDirestorySelector.SelectedPath;
}
//Processing code
}
You want to set the RootFolder property before you show the dialog.
Alternatively if the folder path is custom (and not a special folder), you simply need to set the SelectedPath property before showing the dialog (there are some rules around the path being set, explained in the "Remarks" section of the documentation I linked).

Template per url

I'm looking for an example of how to run a custom page template for a single url in drupal 6, would be nice to have a preprocess function too.
I used the following code in a recent Drupal 6 project; it requires entries into the template.php file which resides in the root of your theme folder. Simply drop the template page you create into the root of your theme folder, and you're off. {:¬)
You may have this function specified in your template.php file already; in which case, you'd probably have to refactor to add this. Here's the function in full:
function yourThemeName_preprocess_page(&$vars) {
if (isset($vars['node'])) {
$node = $vars['node'];
$vars['template_files'] = array();
switch ($node->nid) {
case '17': /* to override a specific node ID */
$vars['template_files'][] = 'page-my-page-name';
break;
default: /* to override a content type */
switch ($node->type) {
case 'page':
$vars['template_files'][] = 'page-normal-page';
break;
case 'my_own_content_type':
$vars['template_files'][] = 'page-my-own-content-type';
break;
default:
/* take no action */
}
}
}
}
Where I've specified 'page-my-page-name', note that Drupal (or rather, PHPTemplate) will add the '.tpl.php' part automatically.
This enables you to override by node ID first (more specific), and then more generally by content type, e.g. story or page. To add more overrides, just add more cases in the right place.
Hope this helps.
Humm, you might have to use the Module Panels3 and create a landing page. You can override every element of that page (even outside content area)

Create a directory on UNC Path web part sharepoint

I have created a web part which renders a button, on click of this button I want to access the directory of the other machine in LAN. Once I get the access to this Directory I will create a nested directories inside it with different extensions of files, but the problem is when I tries to access this folder by UNC Path it is giving me error like "Could not find a part of the path '\comp01\ibc'". Here comp01 is the computer name which is situated in LAN and ibc is a shared folder on that machine.
Following is the code for button click,
void _btnBackup_Click(object sender, EventArgs e)
{
try
{
//UNC Path --> \\In-Wai-Svr2\IBC
if (!string.IsNullOrEmpty(UncPath))
{
SPSite currentSite = SPControl.GetContextSite(this.Context);
SPWeb parentWeb = currentSite.OpenWeb();
string dir = Path.GetDirectoryName(UncPath);
//If IBC folder does not exist then create it.
if(!Directory.Exists(dir))
Directory.CreateDirectory(dir);
IterateThroughChildren(parentWeb, UncPath);
}
else
{
_lblMessage.Text = "UNC Path should not be empty";
}
}
catch(Exception ex)
{
_lblMessage.Text = ex.Message;
}
}
For UNC paths you need to specify it like this:
either use a C# string literal
String path = #"\\comp01\ibc";
or escape the string like
String path = "\\\\comp01\\ibc"
Try that.

Resources