New feature: Opens file in its default viewer

This feature has the same effect as double-clicking this file in Windows Explorer.

Closes #3577, fixes #3576
This commit is contained in:
Cyrillev 2017-07-30 09:10:36 +02:00 committed by Don HO
parent 2593d64fbb
commit fbbe9344d9
11 changed files with 107 additions and 31 deletions

View File

@ -91,7 +91,7 @@
<Item id="41017" name="Rename..."/> <Item id="41017" name="Rename..."/>
<Item id="41021" name="Restore Recent Closed File"/> <Item id="41021" name="Restore Recent Closed File"/>
<Item id="41022" name="Open Folder as &amp;Workspace"/> <Item id="41022" name="Open Folder as &amp;Workspace"/>
<Item id="41023" name="Open in Default Viewer"/>
<Item id="42001" name="Cu&amp;t"/> <Item id="42001" name="Cu&amp;t"/>
<Item id="42002" name="&amp;Copy"/> <Item id="42002" name="&amp;Copy"/>
<Item id="42003" name="&amp;Undo"/> <Item id="42003" name="&amp;Undo"/>
@ -334,6 +334,7 @@
<Item CMID="18" name="Close All to the Right"/> <Item CMID="18" name="Close All to the Right"/>
<Item CMID="19" name="Open Containing Folder in Explorer"/> <Item CMID="19" name="Open Containing Folder in Explorer"/>
<Item CMID="20" name="Open Containing Folder in cmd"/> <Item CMID="20" name="Open Containing Folder in cmd"/>
<Item CMID="21" name="Open in Default Viewer"/>
</TabBar> </TabBar>
</Menu> </Menu>

View File

@ -95,6 +95,7 @@
<Item id="41017" name="Renommer..."/> <Item id="41017" name="Renommer..."/>
<Item id="41021" name="Ouvrir le dernier fichier fermé"/> <Item id="41021" name="Ouvrir le dernier fichier fermé"/>
<Item id="41022" name="Ouvrir Dossier en tant qu'Espace de travail"/> <Item id="41022" name="Ouvrir Dossier en tant qu'Espace de travail"/>
<Item id="41023" name="Ouvrir dans l'application par défaut"/>
<Item id="42001" name="Cou&amp;per"/> <Item id="42001" name="Cou&amp;per"/>
<Item id="42002" name="&amp;Copier"/> <Item id="42002" name="&amp;Copier"/>
<Item id="42003" name="&amp;Annuler"/> <Item id="42003" name="&amp;Annuler"/>
@ -331,6 +332,7 @@
<Item CMID="18" name="Fermer les onglets sur la droite"/> <Item CMID="18" name="Fermer les onglets sur la droite"/>
<Item CMID="19" name="Ouvrir le répertoire du fichier en cours dans Explorer"/> <Item CMID="19" name="Ouvrir le répertoire du fichier en cours dans Explorer"/>
<Item CMID="20" name="Ouvrir le répertoire du fichier en cours dans cmd"/> <Item CMID="20" name="Ouvrir le répertoire du fichier en cours dans cmd"/>
<Item CMID="21" name="Ouvrir dans l'application par défaut"/>
</TabBar> </TabBar>
</Menu> </Menu>
<Dialog> <Dialog>

View File

@ -1101,3 +1101,28 @@ bool isCertificateValidated(const generic_string & fullFilePath, const generic_s
return isOK; return isOK;
} }
bool isAssoCommandExisting(LPCTSTR FullPathName)
{
bool isAssoCommandExisting = false;
bool isFileExisting = PathFileExists(FullPathName) != FALSE;
if (isFileExisting)
{
PTSTR ext = PathFindExtension(FullPathName);
HRESULT hres;
wchar_t buffer[MAX_PATH] = TEXT("");
DWORD bufferLen = MAX_PATH;
// check if association exist
hres = AssocQueryString(ASSOCF_VERIFY|ASSOCF_INIT_IGNOREUNKNOWN, ASSOCSTR_COMMAND, ext, NULL, buffer, &bufferLen);
isAssoCommandExisting = (hres == S_OK) // check if association exist and no error
&& (buffer != NULL) // check if buffer is not NULL
&& (wcsstr(buffer, TEXT("notepad++.exe")) == NULL); // check association with notepad++
}
return isAssoCommandExisting;
}

View File

@ -187,3 +187,4 @@ generic_string uintToString(unsigned int val);
HWND CreateToolTip(int toolID, HWND hDlg, HINSTANCE hInst, const PTSTR pszText); HWND CreateToolTip(int toolID, HWND hDlg, HINSTANCE hInst, const PTSTR pszText);
bool isCertificateValidated(const generic_string & fullFilePath, const generic_string & subjectName2check); bool isCertificateValidated(const generic_string & fullFilePath, const generic_string & subjectName2check);
bool isAssoCommandExisting(LPCTSTR FullPathName);

View File

@ -49,6 +49,7 @@
#include "functionListPanel.h" #include "functionListPanel.h"
#include "fileBrowser.h" #include "fileBrowser.h"
#include "LongRunningOperation.h" #include "LongRunningOperation.h"
#include "Common.h"
using namespace std; using namespace std;
@ -1943,6 +1944,8 @@ void Notepad_plus::checkDocState()
enableCommand(IDM_FILE_OPEN_FOLDER, isFileExisting, MENU); enableCommand(IDM_FILE_OPEN_FOLDER, isFileExisting, MENU);
enableCommand(IDM_FILE_RELOAD, isFileExisting, MENU); enableCommand(IDM_FILE_RELOAD, isFileExisting, MENU);
enableCommand(IDM_FILE_OPEN_DEFAULT_VIEWER, isAssoCommandExisting(curBuf->getFullPathName()), MENU);
enableConvertMenuItems(curBuf->getEolFormat()); enableConvertMenuItems(curBuf->getEolFormat());
checkUnicodeMenuItems(); checkUnicodeMenuItems();
checkLangsMenu(-1); checkLangsMenu(-1);

View File

@ -222,6 +222,7 @@ BEGIN
MENUITEM "Explorer", IDM_FILE_OPEN_FOLDER MENUITEM "Explorer", IDM_FILE_OPEN_FOLDER
MENUITEM "cmd", IDM_FILE_OPEN_CMD MENUITEM "cmd", IDM_FILE_OPEN_CMD
END END
MENUITEM "Open in Default Viewer" IDM_FILE_OPEN_DEFAULT_VIEWER
MENUITEM "Open Folder as Workspace...", IDM_FILE_OPENFOLDERASWORSPACE MENUITEM "Open Folder as Workspace...", IDM_FILE_OPENFOLDERASWORSPACE
MENUITEM "Re&load from Disk", IDM_FILE_RELOAD MENUITEM "Re&load from Disk", IDM_FILE_RELOAD
MENUITEM "&Save", IDM_FILE_SAVE MENUITEM "&Save", IDM_FILE_SAVE

View File

@ -105,6 +105,34 @@ void Notepad_plus::command(int id)
} }
break; break;
case IDM_FILE_OPEN_DEFAULT_VIEWER:
{
// Opens file in its default viewer.
// Has the same effect as doubleclicking this file in Windows Explorer.
BufferID buf = _pEditView->getCurrentBufferID();
HINSTANCE res = ::ShellExecute(NULL, TEXT("open"), buf->getFullPathName(), NULL, NULL, SW_SHOW);
// As per MSDN (https://msdn.microsoft.com/en-us/library/windows/desktop/bb762153(v=vs.85).aspx)
// If the function succeeds, it returns a value greater than 32.
// If the function fails, it returns an error value that indicates the cause of the failure.
int retResult = reinterpret_cast<int>(res);
if (retResult <= 32)
{
generic_string errorMsg;
errorMsg += GetLastErrorAsString(retResult);
errorMsg += TEXT("An attempt was made to execute the below command.");
errorMsg += TEXT("\n----------------------------------------------------------");
errorMsg += TEXT("\nCommand: ");
errorMsg += buf->getFullPathName();
errorMsg += TEXT("\nError Code: ");
errorMsg += intToString(retResult);
errorMsg += TEXT("\n----------------------------------------------------------");
::MessageBox(_pPublicInterface->getHSelf(), errorMsg.c_str(), TEXT("ShellExecute - ERROR"), MB_ICONINFORMATION | MB_APPLMODAL);
}
}
break;
case IDM_FILE_OPENFOLDERASWORSPACE: case IDM_FILE_OPENFOLDERASWORSPACE:
{ {
generic_string folderPath = folderBrowser(_pPublicInterface->getHSelf(), TEXT("Select a folder to add in Folder as Workspace panel")); generic_string folderPath = folderBrowser(_pPublicInterface->getHSelf(), TEXT("Select a folder to add in Folder as Workspace panel"));

View File

@ -32,6 +32,7 @@
#include "VerticalFileSwitcher.h" #include "VerticalFileSwitcher.h"
#include "ProjectPanel.h" #include "ProjectPanel.h"
#include "documentMap.h" #include "documentMap.h"
#include "Common.h"
#include <stack> #include <stack>
using namespace std; using namespace std;
@ -514,7 +515,8 @@ BOOL Notepad_plus::notify(SCNotification *notification)
if (!_tabPopupMenu.isCreated()) if (!_tabPopupMenu.isCreated())
{ {
std::vector<MenuItemUnit> itemUnitArray; // IMPORTANT: If list below is modified, you have to change the value of tabContextMenuItemPos[] in localization.cpp file
std::vector<MenuItemUnit> itemUnitArray;
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_CLOSE, TEXT("Close"))); itemUnitArray.push_back(MenuItemUnit(IDM_FILE_CLOSE, TEXT("Close")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_CLOSEALL_BUT_CURRENT, TEXT("Close All BUT This"))); itemUnitArray.push_back(MenuItemUnit(IDM_FILE_CLOSEALL_BUT_CURRENT, TEXT("Close All BUT This")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_CLOSEALL_TOLEFT, TEXT("Close All to the Left"))); itemUnitArray.push_back(MenuItemUnit(IDM_FILE_CLOSEALL_TOLEFT, TEXT("Close All to the Left")));
@ -529,6 +531,8 @@ BOOL Notepad_plus::notify(SCNotification *notification)
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_OPEN_FOLDER, TEXT("Open Containing Folder in Explorer"))); itemUnitArray.push_back(MenuItemUnit(IDM_FILE_OPEN_FOLDER, TEXT("Open Containing Folder in Explorer")));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_OPEN_CMD, TEXT("Open Containing Folder in cmd"))); itemUnitArray.push_back(MenuItemUnit(IDM_FILE_OPEN_CMD, TEXT("Open Containing Folder in cmd")));
itemUnitArray.push_back(MenuItemUnit(0, NULL)); itemUnitArray.push_back(MenuItemUnit(0, NULL));
itemUnitArray.push_back(MenuItemUnit(IDM_FILE_OPEN_DEFAULT_VIEWER, TEXT("Open in Default Viewer")));
itemUnitArray.push_back(MenuItemUnit(0, NULL));
itemUnitArray.push_back(MenuItemUnit(IDM_EDIT_SETREADONLY, TEXT("Read-Only"))); itemUnitArray.push_back(MenuItemUnit(IDM_EDIT_SETREADONLY, TEXT("Read-Only")));
itemUnitArray.push_back(MenuItemUnit(IDM_EDIT_CLEARREADONLY, TEXT("Clear Read-Only Flag"))); itemUnitArray.push_back(MenuItemUnit(IDM_EDIT_CLEARREADONLY, TEXT("Clear Read-Only Flag")));
itemUnitArray.push_back(MenuItemUnit(0, NULL)); itemUnitArray.push_back(MenuItemUnit(0, NULL));
@ -540,6 +544,7 @@ BOOL Notepad_plus::notify(SCNotification *notification)
itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_CLONE_TO_ANOTHER_VIEW, TEXT("Clone to Other View"))); itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_CLONE_TO_ANOTHER_VIEW, TEXT("Clone to Other View")));
itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_GOTO_NEW_INSTANCE, TEXT("Move to New Instance"))); itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_GOTO_NEW_INSTANCE, TEXT("Move to New Instance")));
itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_LOAD_IN_NEW_INSTANCE, TEXT("Open in New Instance"))); itemUnitArray.push_back(MenuItemUnit(IDM_VIEW_LOAD_IN_NEW_INSTANCE, TEXT("Open in New Instance")));
// IMPORTANT: If list above is modified, you have to change the value of tabContextMenuItemPos[] in localization.cpp file
_tabPopupMenu.create(_pPublicInterface->getHSelf(), itemUnitArray); _tabPopupMenu.create(_pPublicInterface->getHSelf(), itemUnitArray);
_nativeLangSpeaker.changeLangTabContextMenu(_tabPopupMenu.getMenuHandle()); _nativeLangSpeaker.changeLangTabContextMenu(_tabPopupMenu.getMenuHandle());
@ -560,6 +565,8 @@ BOOL Notepad_plus::notify(SCNotification *notification)
_tabPopupMenu.enableItem(IDM_FILE_DELETE, isFileExisting); _tabPopupMenu.enableItem(IDM_FILE_DELETE, isFileExisting);
_tabPopupMenu.enableItem(IDM_FILE_RENAME, isFileExisting); _tabPopupMenu.enableItem(IDM_FILE_RENAME, isFileExisting);
_tabPopupMenu.enableItem(IDM_FILE_OPEN_DEFAULT_VIEWER, isAssoCommandExisting(buf->getFullPathName()));
bool isDirty = buf->isDirty(); bool isDirty = buf->isDirty();
bool isUntitled = buf->isUntitled(); bool isUntitled = buf->isUntitled();
_tabPopupMenu.enableItem(IDM_VIEW_GOTO_NEW_INSTANCE, !(isDirty||isUntitled)); _tabPopupMenu.enableItem(IDM_VIEW_GOTO_NEW_INSTANCE, !(isDirty||isUntitled));

View File

@ -81,6 +81,7 @@ static const WinMenuKeyDefinition winKeyDefs[] =
{ VK_O, IDM_FILE_OPEN, true, false, false, nullptr }, { VK_O, IDM_FILE_OPEN, true, false, false, nullptr },
{ VK_NULL, IDM_FILE_OPEN_FOLDER, false, false, false, nullptr }, { VK_NULL, IDM_FILE_OPEN_FOLDER, false, false, false, nullptr },
{ VK_NULL, IDM_FILE_OPEN_CMD, false, false, false, nullptr }, { VK_NULL, IDM_FILE_OPEN_CMD, false, false, false, nullptr },
{ VK_NULL, IDM_FILE_OPEN_DEFAULT_VIEWER, false, false, false, nullptr },
{ VK_NULL, IDM_FILE_OPENFOLDERASWORSPACE, false, false, false, nullptr }, { VK_NULL, IDM_FILE_OPENFOLDERASWORSPACE, false, false, false, nullptr },
{ VK_NULL, IDM_FILE_RELOAD, false, false, false, nullptr }, { VK_NULL, IDM_FILE_RELOAD, false, false, false, nullptr },
{ VK_S, IDM_FILE_SAVE, true, false, false, nullptr }, { VK_S, IDM_FILE_SAVE, true, false, false, nullptr },

View File

@ -364,27 +364,32 @@ void NativeLangSpeaker::changeMenuLang(HMENU menuHandle, generic_string & plugin
static const int tabContextMenuItemPos[] = static const int tabContextMenuItemPos[] =
{ {
// +-------------- The order in tab menu (NppNotification.cpp : if (!_tabPopupMenu.isCreated())
// |
// | +------ Number in english.xml (<language>.xml) : <TabBar>
// | |
0, // 0 : Close 0, // 0 : Close
1, // 1 : Close ALL BUT This 1, // 1 : Close ALL BUT This
4, // 2 : Save 4, // 2 : Save
5, // 3 : Save As 5, // 3 : Save As
9, // 4 : Print 9, // 4 : Print
21, // 5 : Move to Other View 23, // 5 : Move to Other View
22, // 6 : Clone to Other View 24, // 6 : Clone to Other View
17, // 7 : Full File Path to Clipboard 19, // 7 : Full File Path to Clipboard
18, // 8 : Filename to Clipboard 20, // 8 : Filename to Clipboard
19, // 9 : Current Dir. Path to Clipboard 21, // 9 : Current Dir. Path to Clipboard
6, // 10: Rename 6, // 10: Rename
7, // 11: Move to Recycle Bin 7, // 11: Move to Recycle Bin
14, // 12: Read-Only 16, // 12: Read-Only
15, // 13: Clear Read-Only Flag 17, // 13: Clear Read-Only Flag
23, // 14: Move to New Instance 25, // 14: Move to New Instance
24, // 15: Open to New Instance 26, // 15: Open to New Instance
8, // 16: Reload 8, // 16: Reload
2, // 17: Close ALL to the Left 2, // 17: Close ALL to the Left
3, // 18: Close ALL to the Right 3, // 18: Close ALL to the Right
11, // 19: Open Containing Folder in Explorer 11, // 19: Open Containing Folder in Explorer
12, // 20: Open Containing Folder in cmd 12, // 20: Open Containing Folder in cmd
14, // 21: Open in Default Viewer
-1 //-------End -1 //-------End
}; };

View File

@ -56,10 +56,11 @@
#define IDM_FILE_OPEN_CMD (IDM_FILE + 20) #define IDM_FILE_OPEN_CMD (IDM_FILE + 20)
#define IDM_FILE_RESTORELASTCLOSEDFILE (IDM_FILE + 21) #define IDM_FILE_RESTORELASTCLOSEDFILE (IDM_FILE + 21)
#define IDM_FILE_OPENFOLDERASWORSPACE (IDM_FILE + 22) #define IDM_FILE_OPENFOLDERASWORSPACE (IDM_FILE + 22)
#define IDM_FILE_OPEN_DEFAULT_VIEWER (IDM_FILE + 23)
// IMPORTANT: If list above is modified, you have to change the following values: // IMPORTANT: If list above is modified, you have to change the following values:
// To be updated if new menu item(s) is (are) added in menu "File" // To be updated if new menu item(s) is (are) added in menu "File"
#define IDM_FILEMENU_LASTONE IDM_FILE_OPENFOLDERASWORSPACE #define IDM_FILEMENU_LASTONE IDM_FILE_OPEN_DEFAULT_VIEWER
// 0 based position of command "Exit" including the bars in the file menu // 0 based position of command "Exit" including the bars in the file menu
// and without counting "Recent files history" items // and without counting "Recent files history" items
@ -68,25 +69,26 @@
// 1 Open... // 1 Open...
// 2 Open Containing Folder // 2 Open Containing Folder
// 3 Open Folder as Workspace // 3 Open Folder as Workspace
// 4 Reload from Disk // 4 Open in Default Viewer
// 5 Save // 5 Reload from Disk
// 6 Save As... // 6 Save
// 7 Save a Copy As... // 7 Save As...
// 8 Save All // 8 Save a Copy As...
// 9 Rename... // 9 Save All
//10 Close //10 Rename...
//11 Close All //11 Close
//12 Close More //12 Close All
//13 Move to Recycle Bin //13 Close More
//14 -------- //14 Move to Recycle Bin
//15 Load Session... //15 --------
//16 Save Session... //16 Load Session...
//17 -------- //17 Save Session...
//18 Print... //18 --------
//19 Print Now //19 Print...
//20 -------- //20 Print Now
//21 Exit //21 --------
#define IDM_FILEMENU_EXISTCMDPOSITION 21 //22 Exit
#define IDM_FILEMENU_EXISTCMDPOSITION 22
#define IDM_EDIT (IDM + 2000) #define IDM_EDIT (IDM + 2000)