github.com/benoitkugler/goacve@v0.0.0-20201217100549-151ce6e55dc8/client/GUI/fields/lists.go (about)

     1  package fields
     2  
     3  import (
     4  	"github.com/benoitkugler/goACVE/client/GUI/basic"
     5  	"github.com/benoitkugler/goACVE/client/GUI/lists"
     6  	rd "github.com/benoitkugler/goACVE/server/core/rawdata"
     7  	"github.com/therecipe/qt/widgets"
     8  )
     9  
    10  // stringList permet la modification d'une liste de string
    11  type stringList struct {
    12  	lists.Table
    13  
    14  	title     string
    15  	formatter func(string) string
    16  }
    17  
    18  func newStringList(editable bool, placeholder string) *stringList {
    19  	w := stringList{
    20  		Table: lists.Table{
    21  			Liste: lists.Liste{
    22  				Headers:     []rd.Header{{}},
    23  				Placeholder: placeholder,
    24  			},
    25  			HideHeaders:      true,
    26  			ResizeToContents: true,
    27  		},
    28  	}
    29  
    30  	if editable {
    31  		w.OnDoubleClick = func(acces rd.Item, index int) {
    32  			tel := w.editString(acces.Fields.Data(0).String())
    33  			if tel == "" { // annule
    34  				return
    35  			}
    36  			data := w.GetData()
    37  			data[index] = tel
    38  			w.SetData(data)
    39  		}
    40  		w.OnAdd = func() {
    41  			tel := w.editString("")
    42  			if tel == "" { // annule
    43  				return
    44  			}
    45  			w.SetData(append(w.GetData(), tel))
    46  		}
    47  		w.OnDelete = func(_ rd.Item, index int) {
    48  			data := w.GetData()
    49  			w.SetData(append(data[:index], data[index+1:]...))
    50  		}
    51  	}
    52  	w.Init()
    53  	return &w
    54  }
    55  
    56  // empty string to cancel
    57  func (f stringList) editString(tel string) string {
    58  	dialog := basic.Dialog2(f.title)
    59  	layout := widgets.NewQFormLayout(dialog)
    60  	edit := NewString(true)
    61  	msg := "Ajouter"
    62  	if tel != "" {
    63  		msg = "Modifier"
    64  	}
    65  	edit.SetData(rd.String(tel))
    66  	valid := basic.Button(msg)
    67  
    68  	var out string
    69  	valid.ConnectClicked(func(_ bool) {
    70  		out = edit.GetData().String()
    71  		dialog.Accept()
    72  	})
    73  
    74  	layout.AddRow3(f.title+" :", edit)
    75  	layout.AddRow5(valid)
    76  
    77  	dialog.Exec()
    78  	if f.formatter != nil {
    79  		out = f.formatter(out)
    80  	}
    81  	return out
    82  }
    83  
    84  func (f stringList) GetData() []string {
    85  	data := f.Model().GetData()
    86  	out := make([]string, len(data))
    87  	for index, d := range data {
    88  		out[index] = d.Fields.Data(0).String()
    89  	}
    90  	return out
    91  }
    92  
    93  func (f stringList) SetData(data []string) {
    94  	modelData := make([]rd.Item, len(data))
    95  	for index, d := range data {
    96  		if f.formatter != nil {
    97  			d = f.formatter(d)
    98  		}
    99  		modelData[index] = rd.Item{Fields: rd.F{0: rd.String(d)}}
   100  	}
   101  	f.Model().SetData(modelData)
   102  }
   103  
   104  // Tels permet la modification d'une liste de numéros de téléphones
   105  type Tels struct {
   106  	*stringList
   107  }
   108  
   109  func NewTels(editable bool) Tels {
   110  	w := newStringList(editable, "Aucun numéro.")
   111  	w.title = "Numéro de téléphone"
   112  	w.formatter = rd.FormatTel
   113  
   114  	return Tels{w}
   115  }
   116  
   117  func (f Tels) GetData() rd.Tels {
   118  	return f.stringList.GetData()
   119  }
   120  
   121  func (f Tels) SetData(data rd.Tels) {
   122  	f.stringList.SetData(data)
   123  }
   124  
   125  // Mails permet la modification d'une liste d'adresses mails
   126  type Mails struct {
   127  	*stringList
   128  }
   129  
   130  func NewMails(editable bool) Mails {
   131  	w := newStringList(editable, "Aucun mail.")
   132  	w.title = "Mail"
   133  	w.formatter = nil
   134  
   135  	return Mails{w}
   136  }
   137  
   138  type optionStatut struct {
   139  	*widgets.QFrame
   140  
   141  	table lists.Table
   142  
   143  	// données sous-jacentes à synchroniser
   144  	data []rd.PrixParStatut
   145  }
   146  
   147  func newOptionStatut(editable bool) *optionStatut {
   148  	w := &optionStatut{QFrame: basic.Frame()}
   149  	outerLayout := widgets.NewQVBoxLayout2(w)
   150  
   151  	w.table = lists.Table{
   152  		Liste: lists.Liste{
   153  			Headers: []rd.Header{
   154  				{Field: rd.PPSStatut, Label: "Statut"},
   155  				{Field: rd.PPSPrix, Label: "Prix"},
   156  				{Field: rd.PPSDescription, Label: "Description"},
   157  			},
   158  			Placeholder: "Aucun statut spécial n'est enregistré.",
   159  		},
   160  		ResizeToContents: true,
   161  	}
   162  
   163  	if editable {
   164  		w.table.OnDoubleClick = func(_ rd.Item, index int) {
   165  			ptr := editStatut(w.data[index])
   166  			if ptr == nil {
   167  				return
   168  			}
   169  			data := w.GetData()
   170  			data[index] = *ptr
   171  			w.SetData(data)
   172  		}
   173  		w.table.OnAdd = func() {
   174  			ptr := editStatut(rd.PrixParStatut{})
   175  			if ptr == nil {
   176  				return
   177  			}
   178  			ptr.Id = nextId(w.GetData())
   179  			w.SetData(append(w.GetData(), *ptr))
   180  		}
   181  		w.table.OnDelete = func(_ rd.Item, index int) {
   182  			data := w.GetData()
   183  			w.SetData(append(data[:index], data[index+1:]...))
   184  		}
   185  	}
   186  
   187  	w.table.Init()
   188  	outerLayout.AddWidget(basic.Label(`<i>Le prix dépend du statut du participant. 
   189  		Le statut est attribué parmi la liste ci-dessous.</i><br>`), 0, 0)
   190  	outerLayout.AddWidget(w.table, 1, 0)
   191  	w.SetEnabled(editable)
   192  	return w
   193  }
   194  
   195  // s'assure de renvoyer un id valide, c'est à dire >= 1
   196  func nextId(currents []rd.PrixParStatut) int64 {
   197  	var max int64
   198  	for _, statut := range currents {
   199  		if max < statut.Id {
   200  			max = statut.Id
   201  		}
   202  	}
   203  	return max + 1
   204  }
   205  
   206  func editStatut(item rd.PrixParStatut) *rd.PrixParStatut {
   207  	title := "Ajouter un statut spécial"
   208  	if item.Statut != "" {
   209  		title = "Modifier le statut"
   210  	}
   211  	d := basic.Dialog2(title)
   212  	lay := widgets.NewQFormLayout(d)
   213  	statut := NewString2(true, 20, nil)
   214  	statut.SetToolTip("Statut affiché sur la facture.")
   215  	desc := NewString(true)
   216  	desc.SetToolTip("Description affichée sur le formulaire d'inscription.")
   217  	prix := NewEuros(true)
   218  
   219  	valid := basic.Button("Valider")
   220  	valid.ConnectClicked(func(checked bool) {
   221  		d.Accept()
   222  	})
   223  	statut.SetData(item.Statut)
   224  	desc.SetData(item.Description)
   225  	prix.SetData(item.Prix)
   226  	lay.AddRow3("Statut", statut)
   227  	lay.AddRow3("Description", desc)
   228  	lay.AddRow3("Prix", prix)
   229  	lay.AddRow5(valid)
   230  
   231  	if d.Exec() == 0 {
   232  		return nil
   233  	}
   234  	item.Description = desc.GetData()
   235  	item.Statut = statut.GetData()
   236  	item.Prix = prix.GetData()
   237  	return &item
   238  }
   239  
   240  func (f optionStatut) GetData() []rd.PrixParStatut {
   241  	return f.data
   242  }
   243  
   244  func (f *optionStatut) SetData(data []rd.PrixParStatut) {
   245  	f.data = data
   246  	items := make([]rd.Item, len(data))
   247  	for index, prix := range data {
   248  		items[index] = prix.AsItem()
   249  	}
   250  	f.table.Model().SetData(items)
   251  }
   252  
   253  // ------------------ Destinataires ---------------------
   254  
   255  type Destinataires struct {
   256  	lists.Table
   257  
   258  	// données sous-jacentes à synchroniser
   259  	data rd.DestinatairesOptionnels
   260  
   261  	OnClick func(destinataire rd.Destinataire)
   262  }
   263  
   264  func NewDestinataires(editable bool) *Destinataires {
   265  	w := Destinataires{}
   266  	w.Table = lists.Table{
   267  		Liste: lists.Liste{
   268  			MinHeight: 300,
   269  			Headers: []rd.Header{
   270  				{Field: rd.DNomPrenom, Label: "Destinataire"},
   271  			},
   272  			Placeholder: "Aucun destinataire supplémentaire n'est enregistré.",
   273  		},
   274  		ResizeToContents: true,
   275  	}
   276  
   277  	if editable {
   278  		w.OnDoubleClick = func(_ rd.Item, index int) {
   279  			dest, ok := editDestinataire(w.data[index], editable)
   280  			if !ok {
   281  				return
   282  			}
   283  			data := w.GetData()
   284  			data[index] = dest
   285  			w.SetData(data)
   286  		}
   287  		w.OnAdd = func() {
   288  			dest, ok := editDestinataire(rd.Destinataire{}, editable)
   289  			if !ok {
   290  				return
   291  			}
   292  			w.SetData(append(w.GetData(), dest))
   293  		}
   294  		w.OnDelete = func(_ rd.Item, index int) {
   295  			data := w.GetData()
   296  			w.SetData(append(data[:index], data[index+1:]...))
   297  		}
   298  	}
   299  
   300  	w.Table.OnClick = func(_ rd.Item, index int) {
   301  		if w.OnClick != nil {
   302  			w.OnClick(w.GetData()[index])
   303  		}
   304  	}
   305  	w.Table.Init()
   306  	return &w
   307  }
   308  
   309  func (f Destinataires) GetData() rd.DestinatairesOptionnels {
   310  	return f.data
   311  }
   312  
   313  func (f *Destinataires) SetData(data rd.DestinatairesOptionnels) {
   314  	f.data = data
   315  	items := make([]rd.Item, len(data))
   316  	for index, prix := range data {
   317  		items[index] = prix.AsItem()
   318  	}
   319  	f.Model().SetData(items)
   320  }
   321  
   322  func editDestinataire(destinataire rd.Destinataire, editable bool) (rd.Destinataire, bool) {
   323  	d := basic.Dialog2("Destinataire")
   324  
   325  	nomPrenom := NewString(editable)
   326  	sexe := NewSexe(editable)
   327  	adresse := NewMultiLineString(editable, "Adresse...")
   328  	codePostal := NewString(editable)
   329  	ville := NewString(editable)
   330  
   331  	nomPrenom.SetData(destinataire.NomPrenom)
   332  	sexe.SetData(destinataire.Sexe)
   333  	adresse.SetData(destinataire.Adresse)
   334  	codePostal.SetData(destinataire.CodePostal)
   335  	ville.SetData(destinataire.Ville)
   336  
   337  	lay := widgets.NewQFormLayout(d)
   338  	lay.AddRow3("Destinataire", nomPrenom)
   339  	lay.AddRow3("Sexe", sexe)
   340  	lay.AddRow3("Adresse", adresse)
   341  	lay.AddRow3("Code postal", codePostal)
   342  	lay.AddRow3("Ville", ville)
   343  
   344  	if editable {
   345  		valid := basic.Button("Valider")
   346  		valid.ConnectClicked(func(_ bool) {
   347  			d.Accept()
   348  		})
   349  
   350  		lay.AddRow5(valid)
   351  	}
   352  
   353  	ok := d.Exec() > 0
   354  	out := rd.Destinataire{
   355  		NomPrenom:  nomPrenom.GetData(),
   356  		Sexe:       sexe.GetData(),
   357  		Adresse:    adresse.GetData(),
   358  		CodePostal: codePostal.GetData(),
   359  		Ville:      ville.GetData(),
   360  	}
   361  	return out, ok
   362  }