View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0031993 | Lazarus | LCL | public | 2017-06-09 21:33 | 2017-06-29 15:52 |
Reporter | Soner | Assigned To | wp | ||
Priority | normal | Severity | minor | Reproducibility | have not tried |
Status | closed | Resolution | fixed | ||
Platform | i386 | OS | Windows | ||
Product Version | 1.6.4 | ||||
Target Version | 1.8RC2 | ||||
Summary | 0031993: (Patch)RadioItems from TDBRadioGroup is changeable also by TDataSet.ReadOnly=true | ||||
Description | RadioItems from TDBRadioGroup is changeable also when associated TDataSet is ReadOnly. The Datafield value does not changed only the Radioitems can be selected. | ||||
Steps To Reproduce | 1) Start the example 2) Click readonly-Button 3) Click on the DBRAdioGroup on the left. 4) Look in the grid, the value doesn't changed only the selected RadioButton is changed. 5) Apply my patch and start the example again. | ||||
Additional Information | This is the Patch (only the last 4 lines): lcl\include\dbradiogroup.inc procedure TDBRadioGroup.UpdateRadioButtonStates; // .. dont change it shows only where to add the patch if (NewValue<>OldValue) and FDatalink.CanModify and not SettingValue then begin // .. dont change it shows only where to add the patch end //; Soner FOLLOWING IS PATCH .......... else if (not DataLink.CanModify) and (DataLink.Field.AsString<>NewValue) then begin fValue:=''; // because in procedure TDBRadioGroup.SetValue is // if FValue=AValue then exit; Value:= OldValue; end; end; | ||||
Tags | No tags attached. | ||||
Fixed in Revision | 55344 | ||||
LazTarget | 1.8 | ||||
Widgetset | Win32/Win64 | ||||
Attached Files |
|
duplicate of | 0021099 | resolved | Luiz Americo | Packages | DBRadioGroup Behavior |
related to | 0032077 | resolved | wp | Lazarus | Access Violation in TDBRadioGroup.UpdateRadioButtonStates |
|
|
|
Please create a proper patch. http://wiki.freepascal.org/Creating_A_Patch |
|
Possible solution that works(note: "and DataLink.Active " ) : Change the file: lcl\include\dbradiogroup.inc Add the end of the procedure TDBRadioGroup.UpdateRadioButtonStates; following lines: //; <- comment out ; else if (not DataLink.CanModify) and (DataLink.Active) and (DataLink.Field.AsString<>NewValue) then begin fValue:=''; // because in procedure TDBRadioGroup.SetValue is: // if FValue=AValue then exit; Value:= OldValue; end; |
|
@Juna Manninen I can't send proper patch, because: - this isn't patch, it is possible solution. - I don't have svn-Version from Lazarus and I can't just download svn-Version, because I have only 56K internet connection (mobile Smart-phone connection). I download new or fixed Versions from Lazarus in Office or by friends. Sorry for misleading issue title, in future I will not call it patch, when it isn't patch. Sorr again. |
|
The initial loading of SVN version takes bandwidth. After that only diffs for the latest changes are downloaded (eg. "svn up") and the bandwidth usage is minimal. You use much more bandwidth when downloading the release versions with binaries and all included. |
|
The patch works, but I am not sure if it fixes the right place. The patch just reverts a change of the radiogroup's ItemIndex if the dataset is readonly. I think the correct fix should not allow the radiogroup to change at all. Unfortunately, TCustomRadioGroup does not have a ReadOnly property, and according to 0021099, it probably will never have one. There is a method "CanModify" which could be overridden to return FDataLink.CanModify, but it does not seem to be fully implemented. |
|
@wp I followed your idea and found possible solution, this works also with normal TRadioButtons. To set the TRadioButtons ClicksDisabled property automatically, we can use TDataLink.SetReadOnly or similar. I set ClicksDisabled in example programm self. Here is possible solution: 1)In lazarus\lcl\interfaces\win32\win32callback.inc //soner: Add this from here ..... // (remove this after moving TButtonControl.ClicksDisabled in public-area) type TButtonControlHack = class(TButtonControl) public property ClicksDisabled; end; // ... to here. //soner: change this function TWindowProcHelper.DoWindowProc: LResult; //.. BM_SETCHECK: begin //LParam holds BST_CHECKED, BST_UNCHECKED or SKIP_LMCHANGE; if LParam <> SKIP_LMCHANGE then LMessage.Msg := LM_CHANGED; if lWinControl is TRadioButton then begin //Soner add this from here ... if (TButtonControlHack(lWinControl).ClicksDisabled) then begin //soner if Ord(TRadioButton(lWinControl).SavedState)<>SendMessage(lWinControl.Handle,BM_GETCHECK,0,0) then Windows.sendMessage(lWinControl.Handle, BM_SETCHECK, Windows.WParam(Ord(TRadioButton(lWinControl).SavedState){BST_UNCHECKED}), Windows.LParam(SKIP_LMCHANGE)); end else // ... to here. //Uncheck siblings if WParam = BST_CHECKED then ClearSiblingRadioButtons(TRadioButton(lWinControl)); //.. // **************************************************** 2) In lazarus\lcl\stdctrls.pp TCustomCheckBox = class(TButtonControl) //.. public constructor Create(TheOwner: TComponent); override; function SavedState: TCheckBoxState; //soner add this (we need this because checked returns current(win32)state not the saved state) // **************************************************** 3) In lazarus\lcl\include\customcheckbox.inc function TCustomCheckBox.SavedState: TCheckBoxState; //soner add this begin Result:=FState; end; // **************************************************** 4) In example programm type TButtonControlHack = class(TButtonControl) public property ClicksDisabled; end; procedure TForm1.BtnReadOnlyClick(Sender: TObject); var i: integer; begin BufDataset1.ReadOnly:=BtnReadOnly.Down; if BufDataset1.ReadOnly then Caption:='ReadOnly' else Caption:='Not ReadOnly'; for i:=0 to DBRadioGroup1.ControlCount-1 do TButtonControlHack(DBRadioGroup1.Controls[i]).ClicksDisabled:=AValue; //test for the normal radiobuttons TButtonControlHack(RadioButton1).ClicksDisabled:=AValue; TButtonControlHack(RadioButton2).ClicksDisabled:=AValue; end; |
|
I would prefer first solution because it is crossplatform and the changed solution needs changes in lcl and it is only for win32-widgetset. |
|
Thank you. I did not yet try to bring your code snippets into current code because I see two main problems: (1) You are referring to win32 interface units. This implies that your code will be working only for Windows. But we need it cross-platform! My preference would be not to touch widgetset code at all because it will become an endless story. (NOTE: When writing this I did not see your previous message # 101081) (2) The name "ClicksDisabled" implies (maybe I am wrong) that the code works only for mouse clicks. But the radiobutton/radiogroup can also be changed by means of the keyboard: Press the accelerator key assigned to the button, or navigate to the requested button by means of the arrow keys and press Space. |
|
The first solution(https://bugs.freepascal.org/view.php?id=31993#c101020) is crossplatform. I am using this for my lazarus. Only the second solution(https://bugs.freepascal.org/view.php?id=31993#c101080) is for win32-interface. But the message part (in TWindowProcHelper.DoWindowProc) can be implemented for other widgetsets. I am happy with first solution and it solves one problem that very rarely apppers. |
|
A non-perfect patch is better than no patch --> applied (r55344). Left a comment in the source that it's only a workaround. Please test and close if ok. This issue will come back, though, because TDBCheckbox suffers from the same problem... |
|
@wp I would make this (the first way) also for TDBCheckbox. This could be third solution to avoid onchanged event (Not tested): 1) Using TButtonControl.ClicksDisabled. I think it is for this Kind of usage: http://lazarus-ccr.sourceforge.net/docs/lcl/stdctrls/tbuttoncontrol.clicksdisabled.html 2)Changing in procedure TCustomRadioGroup.CheckItemIndexChanged; this if FLastClickedItemIndex=FItemIndex then exit; to this: if clicksdisabled and (FLastClickedItemIndex<>FItemIndex) then begin SetItemIndexWithoutEvents(FLastClickedItemIndex); // = SetState-Function exit; end else if FLastClickedItemIndex=FItemIndex then exit; -------------- Now, I close this because this because your patch is okay. |
|
SetItemIndexWithoutEvents - I was searching for something like this, but it does not exist. |
|
Sorry I should write more clearly. It is the SetState-Function from TCustomCheckBox you must move it to protected or public area.(RadioButton is derived from CheckBox). It is exactly the this function from procedure TCustomCheckBox.ApplyChanges: TWSCustomCheckBoxClass(WidgetSetClass).SetState(Self, FState); But you can use SetState from checkbox. I will look all the Radio- and CheckBox related bugs closer today, when i am back at home. |
|
I closed this issue but now it looks like not closed. Close this as solved. Third way is not needed, because: 1.In FCL/LCL is some changes for TDataLink.SetReadOnly needed (for setting TButtonControl.ClicksDisabled). 2. No one shuld use TDBRadioGroup.OnChanged, because TDataset.AfterScroll, TField.OnChange or TField.OnSettext is for database more suitable. |
Date Modified | Username | Field | Change |
---|---|---|---|
2017-06-09 21:33 | Soner | New Issue | |
2017-06-09 21:33 | Soner | File Added: DbRgReadOnlyError-public.7z | |
2017-06-11 10:43 | Juha Manninen | Note Added: 0101018 | |
2017-06-11 14:21 | Soner | Note Added: 0101020 | |
2017-06-11 14:30 | Soner | Note Added: 0101021 | |
2017-06-11 14:33 | Soner | Note Edited: 0101020 | View Revisions |
2017-06-11 20:51 | Juha Manninen | Note Added: 0101027 | |
2017-06-13 00:17 | wp | Relationship added | duplicate of 0021099 |
2017-06-13 00:24 | wp | LazTarget | => - |
2017-06-13 00:24 | wp | Note Added: 0101072 | |
2017-06-13 00:24 | wp | Assigned To | => wp |
2017-06-13 00:24 | wp | Status | new => acknowledged |
2017-06-13 11:48 | Soner | Note Added: 0101080 | |
2017-06-13 12:06 | Soner | Note Added: 0101081 | |
2017-06-13 12:17 | wp | Note Added: 0101083 | |
2017-06-13 12:33 | wp | Note Edited: 0101083 | View Revisions |
2017-06-13 12:38 | Soner | Note Added: 0101085 | |
2017-06-13 13:50 | wp | Fixed in Revision | => 55344 |
2017-06-13 13:50 | wp | LazTarget | - => 1.8 |
2017-06-13 13:50 | wp | Note Added: 0101089 | |
2017-06-13 13:50 | wp | Status | acknowledged => resolved |
2017-06-13 13:50 | wp | Resolution | open => fixed |
2017-06-13 13:50 | wp | Target Version | => 1.8RC2 |
2017-06-13 16:51 | Soner | Note Added: 0101096 | |
2017-06-13 16:51 | Soner | Status | resolved => closed |
2017-06-13 17:05 | wp | Status | closed => assigned |
2017-06-13 17:05 | wp | Resolution | fixed => reopened |
2017-06-13 17:06 | wp | Note Added: 0101097 | |
2017-06-13 17:06 | wp | Status | assigned => feedback |
2017-06-13 17:31 | Soner | Note Added: 0101098 | |
2017-06-13 17:31 | Soner | Status | feedback => assigned |
2017-06-15 14:36 | Soner | Note Added: 0101150 | |
2017-06-15 20:49 | wp | Status | assigned => resolved |
2017-06-15 20:49 | wp | Resolution | reopened => fixed |
2017-06-18 00:49 | Soner | Status | resolved => closed |
2017-06-29 15:52 | wp | Relationship added | related to 0032077 |