");
+ Act_FormStart (ActMFUAct);
+ Act_LinkFormSubmit (Txt_Frequent_actions,"MFU_ACT",NULL);
+ fprintf (Gbl.F.Out," %s"
+ "",
+ Txt_Frequent_ACTIONS);
+ Act_FormEnd ();
+
+ /***** Write list of frequently used actions *****/
+ fprintf (Gbl.F.Out,"
");
+ for (NumAct = 0;
+ NumAct < ListMFUActions->NumActions;
+ NumAct++)
+ {
+ Action = ListMFUActions->Actions[NumAct];
+
+ if ((Title = Act_GetTitleAction (Action)) != NULL)
+ {
+ /* Action string */
+ strncpy (TabStr,Txt_TABS_FULL_TXT[Act_Actions[Action].Tab],128);
+ TabStr[128] = '\0';
+ strncpy (MenuStr,Title,128);
+ MenuStr[128] = '\0';
+ sprintf (TabMenuStr,"%s > %s",TabStr,MenuStr);
+
+ /* Icon and text */
+ fprintf (Gbl.F.Out,"- ");
+ Act_FormStart (Action);
+ Act_LinkFormSubmit (TabMenuStr,NULL,NULL);
+ fprintf (Gbl.F.Out,"",
+ Gbl.Prefs.PathIconSet,Cfg_ICON_ACTION,
+ Act_Actions[Action].Icon,
+ MenuStr);
+ fprintf (Gbl.F.Out," %s",MenuStr);
+ Act_FormEnd ();
+ fprintf (Gbl.F.Out,"
");
+ }
+ }
+ fprintf (Gbl.F.Out,"
");
+
+ /***** End div *****/
+ fprintf (Gbl.F.Out,"
");
+ }
+
+/*****************************************************************************/
+/******************** Update most frequently used actions ********************/
+/*****************************************************************************/
+
+#define MFU_MIN_SCORE 0.5
+#define MFU_MAX_SCORE 100.0
+#define MFU_INCREASE_FACTOR 1.2
+#define MFU_DECREASE_FACTOR 0.99
+
+void MFU_UpdateMFUActions (void)
+ {
+ extern struct Act_Actions Act_Actions[Act_NUM_ACTIONS];
+ char Query[1024];
+ MYSQL_RES *mysql_res;
+ MYSQL_ROW row;
+ float Score;
+
+ /***** In some cases, don't register action *****/
+ if (!Gbl.Usrs.Me.Logged)
+ return;
+ if (Act_Actions[Act_Actions[Gbl.Action.Act].SuperAction].IndexInMenu < 0)
+ return;
+ if (Act_Actions[Gbl.Action.Act].SuperAction == ActMFUAct)
+ return;
+
+ Str_SetDecimalPointToUS (); // To get the decimal point as a dot
+
+ /***** Get current score *****/
+ sprintf (Query,"SELECT Score FROM actions_MFU"
+ " WHERE UsrCod='%ld' AND ActCod='%ld'",
+ Gbl.Usrs.Me.UsrDat.UsrCod,
+ Act_Actions[Act_Actions[Gbl.Action.Act].SuperAction].ActCod);
+ if (DB_QuerySELECT (Query,&mysql_res,"can not get score for current action"))
+ {
+ row = mysql_fetch_row (mysql_res);
+ if (sscanf (row[0],"%f",&Score) != 1)
+ Lay_ShowErrorAndExit ("Error when getting score for current action.");
+ Score *= MFU_INCREASE_FACTOR;
+ if (Score > MFU_MAX_SCORE)
+ Score = MFU_MAX_SCORE;
+ }
+ else
+ Score = MFU_MIN_SCORE; // Initial score for a new action not present in MFU table
+
+ /* Free structure that stores the query result */
+ DB_FreeMySQLResult (&mysql_res);
+
+ /***** Update score for the current action *****/
+ sprintf (Query,"REPLACE INTO actions_MFU"
+ " (UsrCod,ActCod,Score,LastClick)"
+ " VALUES ('%ld','%ld','%f',NOW())",
+ Gbl.Usrs.Me.UsrDat.UsrCod,
+ Act_Actions[Act_Actions[Gbl.Action.Act].SuperAction].ActCod,
+ Score);
+ DB_QueryREPLACE (Query,"can not update most frequently used actions");
+
+ /***** Update score for other actions *****/
+ sprintf (Query,"UPDATE actions_MFU SET Score=GREATEST(Score*'%f','%f')"
+ " WHERE UsrCod='%ld' AND ActCod<>'%ld'",
+ MFU_DECREASE_FACTOR,MFU_MIN_SCORE,
+ Gbl.Usrs.Me.UsrDat.UsrCod,
+ Act_Actions[Act_Actions[Gbl.Action.Act].SuperAction].ActCod);
+ DB_QueryUPDATE (Query,"can not update most frequently used actions");
+
+ Str_SetDecimalPointToLocal (); // Return to local system
+ }
diff --git a/swad_MFU.h b/swad_MFU.h
new file mode 100644
index 000000000..58791bd34
--- /dev/null
+++ b/swad_MFU.h
@@ -0,0 +1,57 @@
+// swad_MFU.h: Most Frequently Used actions
+
+#ifndef _SWAD_MFU
+#define _SWAD_MFU
+/*
+ SWAD (Shared Workspace At a Distance in Spanish),
+ is a web platform developed at the University of Granada (Spain),
+ and used to support university teaching.
+
+ This file is part of SWAD core.
+ Copyright (C) 1999-2016 Antonio Caņas Vargas
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see