Alright so what I am doing is creating a encrypted chat room for my friends and I to mess around in.
I wanted to make a private chat where you could right click their name on the List View and message them.
Currently I a structure with all "users" information like name, time logged on, and List View Number. But that List View number becomes incorrect when a user disconnects because it shifts everyone down by one.
How would I be able to essentially "tie" a user to a List View item? That way no matter how many people log on / off when I click on their name it will PM that person. (I tried to use LVN_ITEMCHANGE because I thought the iItem would change but it didn't to my experiance)
**My Idea*
My Idea was to add a random character field in the ListView item called "token" that way when someone clicks on the name it will find the "token" that would be unique and do it that way. But maybe their is an easier way so that is why I am asking.
Your data structure should not be tracking the ListView items at all. It is just extra data.
Your ListView can associate each list item with a data structure. The LVITEM structure has an lParam field for handling user-defined values:
When you want to add a new user to the ListView, dynamically allocate your data structure and assign that pointer to the LVITEM::lParam field before using the LVM_INSERTITEM message.
When you want to access a particular user's data, retrieve that list item's LVITEM using the LVM_GETITEM message, and then type-cast its lParam to access your data structure.
When you want to remove a user, simply remove that list item using the LVM_DELETEITEM message, and then use the LVN_DELETEITEM notification to free the associated data structure.
Alternatively, use the ListView in virtual mode via the LVS_OWNERDATA window style (see Virtual List-View Style and How to Use Virtual List-View Controls), and then you don't need to use the LVITEM::lParam field at all. Store your data structures in a separate array/container somewhere off to the side, and then use the LVN_GETDISPINFO notification to provide display data to the ListView only when it needs data. When you add/remove users from your array/container, simply use the LVM_SETITEMCOUNT message to update the ListView's item count to match the new array/container count. That way there is always a direct relation between ListView items and container items. Let LVN_GETDISPINFO tell you which array/container item to access.
Related
I have a QAbstractListModel that has a bunch of custom objects stored in it, and you can access the different fields of the custom objects in the model by specifying a role (if this is an improper use of Qt roles let me know because I must be confused). I want to display this data in a user friendly QTableView. I can get things displaying using a proxy model, but the issue is I don't want to display the raw values, I want to display specific data derived from the raw data. So for instance, I don't want a column for both ItemA.foo and ItemA.bar, I want to display just ItemA.foo - ItemA.bar in a single column. And to add to that, I want the automatic update functionality you get with models where if either ItemA.foo or ItemA.bar change, I want the difference column to automatically update and recalculate.
I would think that the way to do this would be to use some kind of table proxy model that listens to the source model, and then populates its own fields with the values derived from the source model and listens for dataChanged() signals from the source model. Then you plug this proxy model in to a QTableView. But to me this sounds like something that should be done in a view. Or is this something that should be done by the delegate? I could even go so far as to do these calculations in the base model itself and add roles specific to these values that should be displayed in the table, but that sounds like I am really overloading the responsibilities of the model.
TLDR: How do you manipulate data from a model in a QTableView? Should I do the data manipulation in the base model and then send that to the QTableView? Should I use a proxy model that manipulates the base data and sends it to the QTableView? Or am I completely misunderstanding something?
and you can access the different fields of the custom objects in the model by specifying a role
If you look at the documentation for Qt::ItemDataRole, you would see that Qt models should indeed provide different data for different roles but each role means some distinguished purpose of the data corresponding to the role. For example, the most commonly used role is probably Qt::DisplayRole as the data for this role defines the content displayed in the view e.g. it's the text in the table cell. If you are satisfied with all the other aspects of the view - font, background etc - you can just return empty QVariant for corresponding roles from your model, the view would figure out these details on its own. If you are using roles as a substitute for columns i.e. to return different pieces of conceptually the same data item, it is probably not the intended use of roles.
For the other part of your question - you can customize the appearance of data displayed in the view through the use of a delegate. For example, you could subclass QStyledItemDelegate, override its displayText method to display ItemA.foo - ItemA.bar instead of just ItemA.foo and then set this delegate into the column of your view corresponding to ItemA.foo via setItemDelegateForColumn. The tricky part here would be to detect changes in both ItemA.foo and ItemA.bar columns which would affect the text displayed in the delegate. A while back I implemented a dedicated class in one of my projects which listens to changes in some column of the original model and "reroutes" the change into another column through signal emitting. I did it to solve this very issue - to catch changes in what delegate should display although technically another model column is affected into which the delegate is not set.
I have a model that retrieves data from a table in a database from a certain SQL query, and shows the items in a QTreeView. The characteristics are:
the data comes from a table, but has an underlying tree structure (some rows are parents that have rows below them as children)
this tree structure is shown in the QTreeView
the children are selectable in the QTreeView (not so the parents)
the table in the database gets updated continuously
in the updates, a children can be added to any existing parent
periodically (with a QTimer) the QTreeView is updated with the contents of the table
Since the children are added at any time to any parent, the first silly approach when updating the QTreeView is clearing it all, and append all the rows again, in form of parent or children, to the QTreeView. This is a 0-order approximation, and it is indeed terrible inefficient. In particular, the following problems appear:
Any existing selection is gone
Any expanded parent showing its children is collapsed (unless ExpandAll is active)
The view is reset to show the very first row.
What is the best solution to this problem? I mean, the first solution I will try will be not to clear the QTreeView, but instead parse all the returned rows from the table, and check for each of them whether the corresponding item in the QTreeView exists, and add it if not. But I wonder if there is a trickiest solution to engage a given table in a database with a QTreeView (I know this exists for a QTableView, but then the tree structure is gone).
This thread mentions a general approach, but this might get tricky quickly, but I am not sure how this would work if the underlying model is changing constantly (i.e. the QModelIndex becoming invalid).
Worst case is that you will have to write your own mechanism to remember the selection before updating and then re-applying it.
I assume you use some model/view implementation? You could enhance your model with a safe selection handling, in case the example mentioned above does not work for you.
I guess this is the case for a self-answer.
As I presumed, after a careful analysis of what data is retrieved from the database, I had to do the following "upgrades" to the retrieval code:
I retrieve, along with the fields I want to show in the view, two identifiers, one for grouping rows and one for sorting items into groups
I also retrieve the internal record ID (an increasing integer number) from the table in the database, in order to ask only for new records in the next retrieval.
In the model population code, I added the following:
I first scan the initial records that may belong to existing groups in the model
When, in the scanning, I reach the last group in the model, this implies that the rest of retrieved records belong to new groups (remember the records are retrieved sorted such that items that belong to the same group are retrieved together)
Then start creating groups and adding items to each group, until we use all the records retrieved.
Finally, it is very important:
the use beginInsertRows() and endInsertRows() before and after inserting new items in the model
capture the sorting status of the view (with sortIndicatorSection() and sortIndicatorOrder()) and re-apply this sorting status after updating the model (with sortByColumn())
Doing that the current position and selection in the QTreeView receiving the model updates are preserved, and the items in the view are added and the view updated transparently for the user.
There is a structure that holds raw data (consider int) and a gui that should visualize this data. Gui part consists of a few models and and a few standard views (table and tree). The value should be presented either as a string or as a picture depend on user choice. There are some additional difficulties: in some cases the text is different for different elements - i.e., for the same column 0 normally means "Ok", but for a particular element it should be printed as "Yes", also depend on a user choice some columns should not print text for 0 values at all, living a cell empty and don't clutter the table; next, sometimes cell should show two values - e.g., current value and requested - something like "Yes -> No". This also applies to the case when user wants to see icons.
I see two options:
The model forms string text itself and store it somewhere (in the model item may be). The model also forms composite icon from base icons if it is needed. In that scenario I can use standard delegate and just use standard roles reimplementing QAbstractItemModel::data() method.
Reimplement delegates' paint() method (actually I need to reimplement delegates anyway because I need custom editors like QComboBox). The delegate can get any information it needs through the model and custom roles in paint() method and form the string or complex icon itself. As a suboption, I suppose, it's possible for a model to compose needed information itself, like returning std::tuple<int /*value*/, int /*requested value*/, int /*source element type*/, bool /*text or icon*/> in data() method for Qt::DisplayRole.
Update: I want add one thought about second option. Presumably delegates were introduced to handle the work of representing data. One of the consequences of that is the flexibility delegates can give. If you want to see a raw number in some column, you can just leave the default delegate, if you want some additional info presented in a cell you can set a special delegate for that specific column. And it seems you don't need even touch the model or something else.
Hi i m new to Sitecore. I want to know how to access any table values from Sitecore Web Database through Sitecore API as i want to fill dropdownlist from a table inside sitecore_web database.How can we use Sitecore Queries to access data from Sitecore_Web Database?
I don't suggest you to access directly Sitecore_Web Database.What do you want to do exactly ?
Sitecore Api has a lot of classes, methods for accesing sitecore items but you don't access directly databases .
Maybe this link will help you.
You need to create some items to fill your dropdown list.
An item is a record in a database. Items are the basic building block of a Sitecore site. An item may represent any kind of information, e.g. a piece of content, a media file, a layout etc.
Items always have a name and and ID that uniquely identifies the item within the database. Items have a template that defines which fields the item contains. An item represent a single version of piece of content is a single language.
An item can be retrieved from a database using Items.
An item may have a number of subitems or children. These child items can be accessed through the Children property. The resulting items are checked for security and workflow before being returned. So while an item may have subitems, the current user may be denied access to them. The Parent property define the single parent item of this item.
An item represents a single version in a single language of a piece of content. The language of the item can be obtained from the Language property, while the version is available from the Version property.
The item must be in Editing state before the name or any field values can be changed. If not, an exception is raised. To enter the Editing state use the BeginEdit method and to end it, use the EndEdit method. The EditContext class can be used as a shortcut to BeginEdit/EndEdit.
I get this from Sitecore Api Documentation
As sitecore climber stated, you would not access the Sitecore database directly - this is not something which is supported by Sitecore. Typically you would achieve this through the Sitecore API using the following steps:
retrieve a node from the Sitecore tree which contains child items representing your dropdown items
retrieve the child items
databind your dropdown list to the list of child items
In an ascx, you could have something like this:
<asp:DropDownList ID="exampleDropDown" runat="server"/>
and in the code-behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
var item = Sitecore.Context.Database.GetItem("/sitecore/content/SiteData/StuffForADropDownList");
if (item != null)
{
exampleDropDown.DataTextField = "Text";
exampleDropDown.DataValueField = "Value";
exampleDropDown.DataSource = from i in item.Children.AsEnumerable<Sitecore.Data.Items.Item>()
select new
{
Text = i["Text"],
Value = i.ID.ToString()
};
exampleDropDown.DataBind();
}
}
}
This example assumes that you have an item at /sitecore/content/SiteData/StuffForADropDownList with some child items, which each have a field called Text.
Default in Sitecore you will NEVER work with real database objects other then objects filled using the Sitecore API. Sitecore API will provide you with data from your Sitecore back-end.
If you want to fill a dropdown with a list of items as datasource try something like this:
var items = Sitecore.Context.Item.GetChildren().toList();
yourdropdown.Datasource = items;
yourdropdown.Databind();
Obviously setting your Datatext and Datevalue key correctly, but that's standard .Net.
In Sitecore, never directly get data out of your database and use the Sitecore API.
Please use the built in services to access the sitecore items. It provides the option to select the database in the Get Item method.
You can access the sitecore service with the below URL:
{Your Site}/sitecore/shell/webservice/service.asmx
Using struts2 how can I keep list values just after click in a jsp button, going through the action and returning to jsp again? Doing this click several times again.
I've been watching that to keep a value from a variable that isn't a list I just need to declare it in the action with it's getter and setter, and put a hidden field or textfield in the jsp, but regarding lists don't worked like that.
You are correct that we need a getter and setters for the respected property in our action class to send and receive date from Action class to JSP and in reverse order.
But since for collection, its not possible to store it in a single field, so you have few options here.
If List is a simple List of String you can create a comma separated string and can use that to go from action to JSP and in reverse order (easy to convert that to list), i will not recommend this approach.
Second option i am thinking to set the list in session and you can always retrieve the list in your action class at any time as per your choice.