summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Bzatek <tbzatek@users.sourceforge.net>2008-11-23 16:59:50 +0100
committerTomas Bzatek <tbzatek@users.sourceforge.net>2008-11-23 16:59:50 +0100
commit2de0a7945bf5941cf0a163b86fa8facbb5b05f2d (patch)
treedb7cb80e32d9736d2d3aed54ee35315d164ae666
parent6c77cc430b1e78bd3d0acf1cc078e60775647956 (diff)
downloadtuxcmd-2de0a7945bf5941cf0a163b86fa8facbb5b05f2d.tar.xz
Connection Manager UI improvements (format change!)v0.6.61
- add Duplicate button - add popup menu on the list view - move selection when deleting - add sorting to the list view - save sorting state + column width - simple cipher saved passwords - use hash keys for each item when saving - allow duplicate entries
-rw-r--r--UConfig.pas27
-rw-r--r--UConnectionManager.pas134
-rw-r--r--UCoreUtils.pas12
-rw-r--r--libgtk_kylix/GTKControls.pas2
4 files changed, 158 insertions, 17 deletions
diff --git a/UConfig.pas b/UConfig.pas
index cfd79d3..3e2ab55 100644
--- a/UConfig.pas
+++ b/UConfig.pas
@@ -25,8 +25,8 @@ uses Classes, ULocale;
resourcestring
ConstAppTitle = 'Tux Commander';
- ConstAboutVersion = '0.6.60-dev';
- ConstAboutBuildDate = '2008-11-17';
+ ConstAboutVersion = '0.6.61-dev';
+ ConstAboutBuildDate = '2008-11-23';
{$IFDEF FPC}
{$INCLUDE fpcver.inc}
@@ -58,6 +58,7 @@ const ConfDefaultNormalItemFGColor = '#000000';
ConstNumPanelColumns = 10;
ConstPathDelim = '#';
ConstFullPathFormatStr = '%s#%s';
+ ConstConnMgrXORKey = 65;
ConstTerminalCommand_xterm = 'xterm -T "TuxCommand" -e sh -c ''%s ; echo -n Press ENTER to exit... ; read''';
ConstTerminalCommand_rxvt = 'rxvt -T "TuxCommand" -e sh -c ''%s ; echo -n Press ENTER to exit... ; read''';
@@ -112,7 +113,7 @@ var ConfPanelSep, ConfRowHeight, ConfRowHeightReal, ConfNumHistoryItems,
ConfUseSmoothScrolling: boolean;
ApplicationShuttingDown: boolean;
- ConfConnMgrActiveItem: integer;
+ ConfConnMgrActiveItem, ConfConnMgrSortColumn, ConfConnMgrSortType, ConfConnMgrColumn1Width: integer;
ConfConnMgrDoNotSavePasswords, ConfConnMgrDoNotSynchronizeKeyring: boolean;
ConfQuickConnectPluginID: string;
@@ -140,7 +141,7 @@ function CheckConfFilesMod(var ChangedMainGUI, ChangedAssoc, ChangedBookmarks, C
implementation
-uses ULibc, SysUtils, UCoreUtils, UCore, UFileAssoc, UCoreClasses, UGnome, UVFSCore;
+uses ULibc, glib2, SysUtils, UCoreUtils, UCore, UFileAssoc, UCoreClasses, UGnome, UVFSCore;
var InternalQuickExit, InternalDeleteHistory: boolean;
InternalMainGUIConfmtime, InternalBookmarksConfmtime, InternalFAssocConfmtime, InternalMounterConfmtime,
@@ -260,6 +261,9 @@ begin
ConfConnMgrDoNotSavePasswords := False;
ConfConnMgrDoNotSynchronizeKeyring := False;
ConfQuickConnectPluginID := '';
+ ConfConnMgrSortColumn := -1;
+ ConfConnMgrSortType := 2;
+ ConfConnMgrColumn1Width := 230;
// Setup default values for colors
@@ -945,6 +949,9 @@ begin
ConfConnMgrDoNotSavePasswords := IniFile.ReadBool('__General', 'ConnMgrDoNotSavePasswords', ConfConnMgrDoNotSavePasswords);
ConfConnMgrDoNotSynchronizeKeyring := IniFile.ReadBool('__General', 'ConnMgrDoNotSynchronizeKeyring', ConfConnMgrDoNotSynchronizeKeyring);
ConfQuickConnectPluginID := IniFile.ReadString('__General', 'QuickConnectPluginID', ConfQuickConnectPluginID);
+ ConfConnMgrSortColumn := IniFile.ReadInteger('__General', 'ConnMgrSortColumn', ConfConnMgrSortColumn);
+ ConfConnMgrSortType := IniFile.ReadInteger('__General', 'ConnMgrSortType', ConfConnMgrSortType);
+ ConfConnMgrColumn1Width := IniFile.ReadInteger('__General', 'ConnMgrColumn1Width', ConfConnMgrColumn1Width);
end else
if Sections[i] = '__QuickConnectHistory' then begin
QuickConnectHistory.Clear;
@@ -957,11 +964,11 @@ begin
end else begin
Item := TConnMgrItem.Create;
with Item do begin
- ConnectionName := Sections[i];
+ ConnectionName := IniFile.ReadString(Sections[i], 'ConnectionName', '');
ServiceType := IniFile.ReadString(Sections[i], 'ServiceType', '');
Server := IniFile.ReadString(Sections[i], 'Server', '');
Username := IniFile.ReadString(Sections[i], 'Username', '');
- Password := IniFile.ReadString(Sections[i], 'Password', '');
+ Password := XORStr(IniFile.ReadString(Sections[i], 'Password', ''), ConstConnMgrXORKey);
TargetDir := IniFile.ReadString(Sections[i], 'TargetDir', '');
PluginID := IniFile.ReadString(Sections[i], 'PluginID', '');
end;
@@ -997,6 +1004,9 @@ begin
IniFile.WriteBool('__General', 'ConnMgrDoNotSavePasswords', ConfConnMgrDoNotSavePasswords);
IniFile.WriteBool('__General', 'ConnMgrDoNotSynchronizeKeyring', ConfConnMgrDoNotSynchronizeKeyring);
IniFile.WriteString('__General', 'QuickConnectPluginID', ConfQuickConnectPluginID);
+ IniFile.WriteInteger('__General', 'ConnMgrSortColumn', ConfConnMgrSortColumn);
+ IniFile.WriteInteger('__General', 'ConnMgrSortType', ConfConnMgrSortType);
+ IniFile.WriteInteger('__General', 'ConnMgrColumn1Width', ConfConnMgrColumn1Width);
IniFile.WriteInteger('__QuickConnectHistory', 'NumItems', QuickConnectHistory.Count);
if QuickConnectHistory.Count > 0 then
for i := 0 to QuickConnectHistory.Count - 1 do
@@ -1004,12 +1014,13 @@ begin
if ConnectionMgrList.Count > 0 then
for i := 0 to ConnectionMgrList.Count - 1 do
with TConnMgrItem(ConnectionMgrList[i]) do begin
- SectionTitle := ConnectionName;
+ SectionTitle := Format('%d_%d_%d', [g_str_hash(PChar(ConnectionName)), i, g_str_hash(PChar(GetURI(False)))]);
IniFile.EraseSection(SectionTitle);
+ IniFile.WriteString(SectionTitle, 'ConnectionName', ConnectionName);
IniFile.WriteString(SectionTitle, 'ServiceType', ServiceType);
IniFile.WriteString(SectionTitle, 'Server', Server);
IniFile.WriteString(SectionTitle, 'Username', Username);
- if not ConfConnMgrDoNotSavePasswords then IniFile.WriteString(SectionTitle, 'Password', Password)
+ if not ConfConnMgrDoNotSavePasswords then IniFile.WriteString(SectionTitle, 'Password', XORStr(Password, ConstConnMgrXORKey))
else IniFile.WriteString(SectionTitle, 'Password', '');
IniFile.WriteString(SectionTitle, 'TargetDir', TargetDir);
IniFile.WriteString(SectionTitle, 'PluginID', PluginID);
diff --git a/UConnectionManager.pas b/UConnectionManager.pas
index 2b39a51..9adcf4f 100644
--- a/UConnectionManager.pas
+++ b/UConnectionManager.pas
@@ -23,7 +23,7 @@ interface
uses
glib2, gdk2, gtk2, pango, SysUtils, Types, Classes, GTKControls, GTKForms, GTKStdCtrls, GTKExtCtrls, GTKConsts, GTKView,
- GTKUtils, GTKDialogs, GTKPixbuf, GTKClasses,
+ GTKUtils, GTKDialogs, GTKPixbuf, GTKClasses, GTKMenus,
UCore, UCoreClasses, UVFSCore, UEngines;
type
@@ -36,12 +36,13 @@ type
ListView: TGTKListView;
ListViewScrolledWindow: TGTKScrolledWindow;
ListViewTable: TGTKTable;
- AddConnectionButton, EditButton, RemoveButton: TGTKImageButton;
+ AddConnectionButton, EditButton, RemoveButton, DuplicateButton: TGTKImageButton;
QuickConnectButton: TGTKImageButton;
ButtonBox: TGTKVButtonBox;
ActionButtonBox: TGTKHButtonBox;
ConnectButton, StopButton, CloseButton: TGTKButton;
DoNotSavePasswordsCheckBox, DoNotSynchronizeKeyringCheckBox: TGTKCheckButton;
+ ItemsPopupMenu, ConnectMenuItem, AddConnectionMenuItem, EditMenuItem, RemoveMenuItem, DuplicateMenuItem: TGTKMenuItem;
procedure FormCreate(Sender: TObject); override;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormResponse(Sender: TObject; const ResponseID: integer);
@@ -49,6 +50,7 @@ type
procedure FormKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean);
procedure AddConnectionButtonClick(Sender: TObject);
procedure EditButtonClick(Sender: TObject);
+ procedure DuplicateButtonClick(Sender: TObject);
procedure RemoveButtonClick(Sender: TObject);
procedure ListViewDblClick(Sender: TObject; Button: TGDKMouseButton; Shift: TShiftState; X, Y: Integer; var Accept: boolean);
procedure ListViewKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean);
@@ -76,6 +78,7 @@ uses ULocale, UCoreUtils, UConfig, UConnectionProperties, UGnome, UQuickConnect;
procedure TFConnectionManager.FormCreate(Sender: TObject);
+const row_targets: TGtkTargetEntry = (target: 'GTK_TREE_MODEL_ROW'; flags: GTK_TARGET_SAME_WIDGET; info: 1;);
var Column: TGTKTreeViewColumn;
begin
Thread := nil;
@@ -128,15 +131,21 @@ begin
ListViewTable.BorderWidth := 7;
ClientArea.AddControlEx(ListViewTable, True, True, 0);
- ListView := TGTKListView.CreateTyped(Self, False, [lcPointer, lcText, lcText]);
+ ListView := TGTKListView.CreateTyped(Self, True, [lcPointer, lcText, lcText]);
+ ListView.SelectionMode := smSingle;
ListView.OnKeyDown := ListViewKeyDown;
+{
+ gtk_tree_view_enable_model_drag_source(GTK_TREE_VIEW(ListView.FWidget), GDK_BUTTON1_MASK, @row_targets, 1, GDK_ACTION_MOVE);
+ gtk_tree_view_enable_model_drag_dest(GTK_TREE_VIEW(ListView.FWidget), @row_targets, 1, GDK_ACTION_MOVE);
+}
+
ListView.RulesHint := True;
ListView.ShowHeaders := True;
Column := ListView.Columns.Add;
Column.AddAttribute('text', 1);
Column.Resizable := True;
- Column.FixedWidth := 230;
+ Column.FixedWidth := ConfConnMgrColumn1Width;
Column.SizingMode := smFixed;
Column.Caption := LANGConnMgr_NameColumn;
Column.Clickable := True;
@@ -148,6 +157,8 @@ begin
Column.Caption := LANGConnMgr_URIColumn;
Column.Clickable := True;
Column.SortID := 2;
+ ListView.SearchColumn := 1;
+ ListView.SetSortInfo(ConfConnMgrSortColumn, TGTKTreeViewSortOrder(ConfConnMgrSortType));
ListViewScrolledWindow := TGTKScrolledWindow.Create(Self);
ListViewScrolledWindow.AddControl(ListView);
ListViewScrolledWindow.HorizScrollBarPolicy := sbAutomatic;
@@ -168,6 +179,10 @@ begin
RemoveButton.Caption := LANGConnMgr_RemoveButtonCaption;
RemoveButton.UseUnderline := True;
RemoveButton.Tooltip := LANGConnMgr_RemoveButtonTooltip;
+ DuplicateButton := TGTKImageButton.Create(Self);
+ DuplicateButton.Caption := 'D_uplicate...';
+ DuplicateButton.UseUnderline := True;
+ DuplicateButton.Tooltip := 'Duplicate selected connection';
QuickConnectButton := TGTKImageButton.Create(Self);
QuickConnectButton.SetFromStock('gtk-connect', isSmallToolbar);
@@ -181,6 +196,7 @@ begin
ButtonBox.AddControl(TGTKEventBox.Create(Self));
ButtonBox.AddControl(AddConnectionButton);
ButtonBox.AddControl(EditButton);
+ ButtonBox.AddControl(DuplicateButton);
ButtonBox.AddControl(RemoveButton);
DoNotSavePasswordsCheckBox := TGTKCheckButton.CreateWithLabel(Self, '_Do not store passwords internally (but still use gnome-keyring)');
@@ -195,14 +211,45 @@ begin
ListViewTable.AddControlEx(3, 5, 1, 1, TGTKLabel.Create(Self), [taoShrink, taoFill], [taoExpand, taoFill], 0, 2);
+ ItemsPopupMenu := TGTKMenuItem.Create(Self);
+ ConnectMenuItem := TGTKMenuItem.CreateTyped(Self, itImageText);
+ ConnectMenuItem.Caption := LANGConnMgr_ConnectButton;
+ ConnectMenuItem.StockIcon := 'gtk-connect';
+ ConnectMenuItem.OnClick := ConnectButtonClick;
+ AddConnectionMenuItem := TGTKMenuItem.CreateTyped(Self, itImageText);
+ AddConnectionMenuItem.Caption := LANGConnMgr_AddConnectionButtonCaption;
+ AddConnectionMenuItem.StockIcon := 'gtk-add';
+ AddConnectionMenuItem.OnClick := AddConnectionButtonClick;
+ EditMenuItem := TGTKMenuItem.CreateTyped(Self, itImageText);
+ EditMenuItem.Caption := LANGConnMgr_EditButtonCaption;
+ EditMenuItem.OnClick := EditButtonClick;
+ RemoveMenuItem := TGTKMenuItem.CreateTyped(Self, itImageText);
+ RemoveMenuItem.Caption := LANGConnMgr_RemoveButtonCaption;
+ RemoveMenuItem.StockIcon := 'gtk-remove';
+ RemoveMenuItem.OnClick := RemoveButtonClick;
+ DuplicateMenuItem := TGTKMenuItem.CreateTyped(Self, itImageText);
+ DuplicateMenuItem.Caption := 'D_uplicate...';
+ DuplicateMenuItem.OnClick := DuplicateButtonClick;
+ ItemsPopupMenu.Add(ConnectMenuItem);
+ ItemsPopupMenu.Add(TGTKMenuItem.CreateTyped(Self, itSeparator));
+ ItemsPopupMenu.Add(AddConnectionMenuItem);
+ ItemsPopupMenu.Add(EditMenuItem);
+ ItemsPopupMenu.Add(DuplicateMenuItem);
+ ItemsPopupMenu.Add(RemoveMenuItem);
+
FillList;
ListView.OnSelectionChanged := ListViewSelectionChanged;
ListView.OnDblClick := ListViewDblClick;
+ ListView.PopupMenu := ItemsPopupMenu;
ListView.SetFocus;
- if ListView.Items.Count > 0 then ListView.Items[ConfConnMgrActiveItem].SetCursor(0, False, False, 0, 0);
+ if (ListView.Items.Count > 0) and (ConfConnMgrActiveItem >= 0) and (ConfConnMgrActiveItem < ListView.Items.Count) then begin
+ ListView.Items[ConfConnMgrActiveItem].Selected := True;
+ ListView.Items[ConfConnMgrActiveItem].SetCursor(0, False, False, 0, 0);
+ end;
ListViewSelectionChanged(Self);
AddConnectionButton.OnClick := AddConnectionButtonClick;
EditButton.OnClick := EditButtonClick;
+ DuplicateButton.OnClick := DuplicateButtonClick;
RemoveButton.OnClick := RemoveButtonClick;
CloseButton.OnClick := CloseButtonClick;
ConnectButton.OnClick := ConnectButtonClick;
@@ -217,8 +264,13 @@ procedure TFConnectionManager.ListViewSelectionChanged(Sender: TObject);
begin
try
EditButton.Enabled := Assigned(ListView.Selected);
+ DuplicateButton.Enabled := Assigned(ListView.Selected);
RemoveButton.Enabled := Assigned(ListView.Selected);
ConnectButton.Enabled := Assigned(ListView.Selected);
+ ConnectMenuItem.Enabled := Assigned(ListView.Selected);
+ EditMenuItem.Enabled := Assigned(ListView.Selected);
+ DuplicateMenuItem.Enabled := Assigned(ListView.Selected);
+ RemoveMenuItem.Enabled := Assigned(ListView.Selected);
except end;
end;
@@ -237,7 +289,8 @@ end;
procedure TFConnectionManager.ListViewDblClick(Sender: TObject; Button: TGDKMouseButton; Shift: TShiftState; X, Y: Integer; var Accept: boolean);
begin
- if Assigned(ListView.Selected) then DoConnect;
+ if Assigned(ListView.Selected) and (Button = mbLeft) and (ListView.GetItemAtPos(X, Y) <> nil)
+ then DoConnect;
end;
procedure TFConnectionManager.ListViewKeyDown(Sender: TObject; Key: Word; Shift: TShiftState; var Accept: boolean);
@@ -252,6 +305,9 @@ begin
if ListView.Selected <> nil then ConfConnMgrActiveItem := ListView.Selected.Index;
ConfConnMgrDoNotSavePasswords := DoNotSavePasswordsCheckBox.Checked;
ConfConnMgrDoNotSynchronizeKeyring := DoNotSynchronizeKeyringCheckBox.Checked;
+ ConfConnMgrSortColumn := ListView.SortColumnID;
+ ConfConnMgrSortType := Integer(ListView.SortOrder);
+ ConfConnMgrColumn1Width := ListView.Columns[0].Width;
end;
procedure TFConnectionManager.FormResponse(Sender: TObject; const ResponseID: integer);
@@ -286,9 +342,12 @@ begin
Item.SetValue(0, ConnMgrItem);
Item.SetValue(1, ConnMgrItem.ConnectionName);
Item.SetValue(2, FConnectionProperties.MakeURI(True));
+ Item.Selected := True;
+ Item.SetCursor(0, False, not Application.GTKVersion_2_2_0_Up, 0.5, 0);
end;
finally
FConnectionProperties.Free;
+ ListView.SetFocus;
end;
end;
@@ -329,21 +388,70 @@ begin
end;
finally
FConnectionProperties.Free;
+ ListView.SetFocus;
end;
end;
-procedure TFConnectionManager.RemoveButtonClick(Sender: TObject);
+procedure TFConnectionManager.DuplicateButtonClick(Sender: TObject);
var Item: TGTKListItem;
ConnMgrItem: TConnMgrItem;
i: integer;
begin
+ try
+ Item := ListView.Selected;
+ if Item = nil then Exit;
+ ConnMgrItem := Item.AsPointer(0);
+ if ConnMgrItem = nil then Exit;
+ FConnectionProperties := TFConnectionProperties.Create(Self);
+ FConnectionProperties.NameEntry.Text := '';
+ FConnectionProperties.URIEntry.Text := ConstructURI(True, False, ConnMgrItem.ServiceType, ConnMgrItem.Server, ConnMgrItem.Username, ConnMgrItem.Password, ConnMgrItem.TargetDir);
+ FConnectionProperties.ServiceTypeOptionMenuChanged(Sender);
+ // Find the plugin by PluginID
+ for i := 0 to PluginList.Count - 1 do
+ if TVFSPlugin(PluginList[i]).VFSName = ConnMgrItem.PluginID then begin
+ FConnectionProperties.PluginOptionMenu.ItemIndex := i + 1;
+ Break;
+ end;
+
+ if FConnectionProperties.Run = mbOK then begin
+ ConnMgrItem := TConnMgrItem.Create;
+ with FConnectionProperties do begin
+ ConnMgrItem.ConnectionName := NameEntry.Text;
+ ConnMgrItem.ServiceType := GetService;
+ ConnMgrItem.Server := ServerEntry.Text;
+ ConnMgrItem.Username := UserNameEntry.Text;
+ ConnMgrItem.Password := PasswordEntry.Text;
+ ConnMgrItem.TargetDir := TargetDirEntry.Text;
+ ConnMgrItem.PluginID := '';
+ if PluginOptionMenu.ItemIndex <> 0 then ConnMgrItem.PluginID := TVFSPlugin(PluginList[PluginOptionMenu.ItemIndex - 1]).VFSName;
+ end;
+ ConnectionMgrList.Add(ConnMgrItem);
+ Item := ListView.Items.Add;
+ Item.SetValue(0, ConnMgrItem);
+ Item.SetValue(1, ConnMgrItem.ConnectionName);
+ Item.SetValue(2, FConnectionProperties.MakeURI(True));
+ Item.Selected := True;
+ Item.SetCursor(0, False, not Application.GTKVersion_2_2_0_Up, 0.5, 0);
+ end;
+ finally
+ FConnectionProperties.Free;
+ ListView.SetFocus;
+ end;
+end;
+
+procedure TFConnectionManager.RemoveButtonClick(Sender: TObject);
+var Item: TGTKListItem;
+ ConnMgrItem: TConnMgrItem;
+ i, OldIndex: integer;
+begin
Item := ListView.Selected;
if Item = nil then Exit;
ConnMgrItem := Item.AsPointer(0);
if ConnMgrItem = nil then Exit;
- if Application.MessageBox(Format(LANGConnMgr_DoYouWantDelete, [Item.AsString(1)]),
+ if Application.MessageBox(PGtkWindow(FWidget), Format(LANGConnMgr_DoYouWantDelete, [Item.AsString(1)]),
[mbYes, mbNo], mbQuestion, mbYes, mbNo) = mbYes then
begin
+ OldIndex := ListView.ConvertToSorted(Item.Index);
if ConnectionMgrList.Count > 0 then
for i := 0 to ConnectionMgrList.Count - 1 do
if ConnectionMgrList[i] = ConnMgrItem then begin
@@ -352,6 +460,16 @@ begin
end;
ConnMgrItem.Free;
ListView.Items.Delete(Item.Index);
+
+ // Preserve selection
+ if ListView.Items.Count > 0 then begin
+ if ListView.Items.Count <= OldIndex
+ then OldIndex := ListView.ConvertFromSorted(ListView.Items.Count - 1)
+ else OldIndex := ListView.ConvertFromSorted(OldIndex);
+ ListView.Items[OldIndex].Selected := True;
+ ListView.Items[OldIndex].SetCursor(0, False, not Application.GTKVersion_2_2_0_Up, 0.5, 0);
+ end;
+ ListView.SetFocus;
end;
end;
diff --git a/UCoreUtils.pas b/UCoreUtils.pas
index fb7056d..7a5a6b1 100644
--- a/UCoreUtils.pas
+++ b/UCoreUtils.pas
@@ -113,6 +113,8 @@ function EnsureUTF8String(s: PChar): PChar; overload;
function Min(Val1, Val2: longint): longint;
+function XORStr(const s: string; Key: byte): string;
+
procedure ReportGTKVersion;
// Internal locking
@@ -1578,6 +1580,16 @@ begin
if Val1 < Val2 then Result := Val1
else Result := Val2;
end;
+
+function XORStr(const s: string; Key: byte): string;
+var i: integer;
+begin
+ Result := s;
+ if Length(Result) > 0 then
+ for i := 1 to Length(Result) do
+ Result[i] := Char(Byte(Result[i]) xor Key);
+end;
+
(********************************************************************************************************************************)
procedure signal_proc(signal_number: integer); cdecl;
diff --git a/libgtk_kylix/GTKControls.pas b/libgtk_kylix/GTKControls.pas
index d839a65..46b03a2 100644
--- a/libgtk_kylix/GTKControls.pas
+++ b/libgtk_kylix/GTKControls.pas
@@ -444,7 +444,7 @@ begin
// if Assigned(TGTKMenuItem(TGTKControl(widget).FPopupMenu).OnPopup) then TGTKMenuItem(TGTKControl(widget).FPopupMenu).OnPopup(TGTKMenuItem(TGTKControl(widget).FPopupMenu));
if Assigned(TGTKMenuItem(TGTKControl(widget).FPopupMenu).OnPopup) then TGTKMenuItem(TGTKControl(widget).FPopupMenu).OnPopup(TGTKControl(widget));
gtk_menu_popup(PGtkMenu(TGTKMenuItem(TGTKControl(widget).FPopupMenu).FMenu), nil, nil, nil, nil, event^.button, event^.time);
- Result := True;
+ Result := False; // Allow list views to process their events - select an item beneath the cursor
end;
end;