diff --git a/Sankore_3.1.pro b/Sankore_3.1.pro index b9ddcd8f..a2b71e9f 100644 --- a/Sankore_3.1.pro +++ b/Sankore_3.1.pro @@ -7,7 +7,7 @@ CONFIG += debug_and_release \ no_include_pwd VERSION_MAJ = 1 -VERSION_MIN = 13 +VERSION_MIN = 15 VERSION_TYPE = b # a = alpha, b = beta, r = release, other => error VERSION_PATCH = 00 diff --git a/resources/forms/mainWindow.ui b/resources/forms/mainWindow.ui index 548c6b59..14ef49c3 100644 --- a/resources/forms/mainWindow.ui +++ b/resources/forms/mainWindow.ui @@ -1551,21 +1551,6 @@ QAction::TextHeuristicRole - - - - :/images/addItemToLibrary.svg:/images/addItemToLibrary.svg - - - Share Item on the Web - - - Share Capture on the Web - - - true - - true diff --git a/resources/library/interactive/Geogebra.wgt/config.xml b/resources/library/interactive/Geogebra.wgt/config.xml new file mode 100644 index 00000000..64bb595c --- /dev/null +++ b/resources/library/interactive/Geogebra.wgt/config.xml @@ -0,0 +1,12 @@ + + + Geogebra + + diff --git a/resources/library/interactive/Geogebra.wgt/icon.png b/resources/library/interactive/Geogebra.wgt/icon.png new file mode 100644 index 00000000..2b5397e4 Binary files /dev/null and b/resources/library/interactive/Geogebra.wgt/icon.png differ diff --git a/resources/library/interactive/Geogebra.wgt/images/loading.gif b/resources/library/interactive/Geogebra.wgt/images/loading.gif new file mode 100644 index 00000000..5ccc287b Binary files /dev/null and b/resources/library/interactive/Geogebra.wgt/images/loading.gif differ diff --git a/resources/library/interactive/Geogebra.wgt/index.html b/resources/library/interactive/Geogebra.wgt/index.html new file mode 100644 index 00000000..9fe49048 --- /dev/null +++ b/resources/library/interactive/Geogebra.wgt/index.html @@ -0,0 +1,71 @@ + + + + +
+ + + diff --git a/resources/library/interactive/Graphme.wgt/Grapheur.xhtml b/resources/library/interactive/Graphme.wgt/Grapheur.xhtml index 2265d6ea..557e657d 100644 --- a/resources/library/interactive/Graphme.wgt/Grapheur.xhtml +++ b/resources/library/interactive/Graphme.wgt/Grapheur.xhtml @@ -6,7 +6,7 @@ - Traceur de fonctions mathématiques + Graphics @@ -28,7 +28,7 @@ var ligne = new Array() var j = 0 - var interdit = new Array(";", "interdit", "'", '"', "eval", "new", "uniboard", "=", "document", "window", "alert") + var interdit = new Array(";", "interdit", "'", '"', "eval", "new", "sankore", "=", "document", "window", "alert") var menuActuel = "" var mouseDown = false @@ -89,7 +89,7 @@ // Cette fonction permet de choisir la méthode d'affichage entre: // 1) Image au format XPM - // 2) Affichage directe dans uniboard + // 2) Affichage directe dans sankore // 3) Autres Méthodes d'affichages (svg ou canvas) function evaluer(eq){ if(check(eq)){ @@ -109,7 +109,7 @@ else if(document.getElementById("selectMethodeAffichage").value == "xpm"){ evaluerXPM(eq) } - else if(document.getElementById("selectMethodeAffichage").value == "uniboard"){ + else if(document.getElementById("selectMethodeAffichage").value == "sankore"){ evaluerUniboard(eq) } else if(document.getElementById("selectMethodeAffichage").value == "canvas" || document.getElementById("selectMethodeAffichage").value == "canvas2"){ @@ -270,8 +270,8 @@ - Fonction : - + Function: +
^
@@ -283,34 +283,34 @@
- Axe des X de:
+ X-axis:
à
- Axe des Y de:
+ Y-axis:
à
Zoom:


- Couleur:
+ Color:




Menus: - + - - + +
- - + +
@@ -325,26 +325,26 @@
-

Options du widget

+

Widget options

- Thème du widget : + + +



- Gèrer les options :
-
- Sauvegarder les options du widget dans les cookies, charger les options depuis les cookies ou supprimer les options actuellement enregistrées. + Control options:
+
+ Save a widget options in cookies or load an options from cookies or delete a registered options.

- +
-


Les cookies sont désactivés, impossible de sauvegarder les options...

-
Vous utilisez la dernière version du widget en ligne.
- - +


Cookies are disabled. You cannot save an options...

+
You are using the last version of this widget.
+ +
-
+
@@ -600,7 +598,7 @@ -

Widget réalisé par

+

Widget is developed by

Yannick Vessaz
yannick.vessaz@gmail.com @@ -608,105 +606,105 @@

- Si vous voulez rapporter un bug, avez une suggestion par rapport au widget ou voulez simplement poser une question, merci de me contacter par e-mail. + If you want to inform about bug, make a proposal or just ask some questions then you can contact to me at the following e-mail: e-mail.

- Les images d'arrière-plan du widget on été tirées des thèmes du bureau "plasma-desktop" de l'environnement KDE. + If you want to change background design then you can contact at following address: KDE.
version 1.3 -
+

-

------- Erreur -------

+

------- Error -------


- Impossible de dessiner la fonction ... + Impossible to draw the function ...

- Expression ou carractère invalide :
+ Error in expression or unexpected char:


@@ -839,34 +837,31 @@
-

------- Erreur -------

- Une erreur s'est produite pendant les calculs nécessaires à afficher la fonction. Vérifiez la fonction que vous vouliez dessiner et appuyez à nouveau sur "afficher". +

------- Error -------

+ Runtime error! Check your function and try to draw it again.
- Une description ainsi que des exemples des différentes fonctions que vous pouvez entrer se trouve dans l'aide. + Description and parameters various functions which are available to help.

- +

-

------- Erreur -------

+

------- Error -------



- Il est impossible de mettre à jour le widget vers la version en ligne car vous utilisez déjà la version en ligne. + Update to latest version is not available because you already use the latest version.


@@ -874,23 +869,12 @@

-

Options sauvegardées!

+

Options saved!


- -
-
-

Mise à jour automatique

-

- Voulez-vous vraiment utiliser la dernière version du widget disponible ? -


- - -
- - +
diff --git a/resources/library/interactive/Graphme.wgt/Guide_Utilisateur.html b/resources/library/interactive/Graphme.wgt/Guide_Utilisateur.html index 61afeb73..2caf6a23 100644 --- a/resources/library/interactive/Graphme.wgt/Guide_Utilisateur.html +++ b/resources/library/interactive/Graphme.wgt/Guide_Utilisateur.html @@ -2,199 +2,199 @@ - GraphMe - Guide utilisateur + GraphMe - User's guide.

GraphMe

-

Guide d'utilisation

+

User's guide

  1. Introduction
  2. Installation
  3. -
  4. Afficher le widget
  5. -
  6. Présentation de l'affichage
  7. -
  8. Dessiner une fonction
  9. -
  10. Se déplacer à travers la fonction
  11. -
  12. Le menu des options
  13. -
  14. Le menu des outils
  15. -
  16. Dessiner plusieurs fonctions
  17. -
  18. Mettre à jour GraphMe
  19. +
  20. Review widget
  21. +
  22. View presentation
  23. +
  24. Drawing the function
  25. +
  26. Offset function
  27. +
  28. The options menu
  29. +
  30. the tools menu
  31. +
  32. Drawing some functions
  33. +
  34. GraphMe update
  35. Contact

1. Introduction

- GraphMe est un traceur de fonctions mathématiques que j'ai programmé dans le cadre du travail de maturité gymnasiale. Il est codé en HTML, CSS et JavaScript. Ce grapheur est disponible sur un cd-rom accompagnant mon travail de maturité ainsi que sur internet à la page http://gyb.educanet2.ch/tm-widgets/.ws_gen/?15. Ce document a pour but d'expliquer comment utiliser GraphMe. Il présente ses différentes fonctions ainsi que quelques astuces utiles à l'utilisateur. + GraphMe is a app that is developed using html, javascript and css. It can be used for drawing graphs. This document must explain how to use GraphMe. This app have a different functions and some useful advices for users.

2. Installation

- Le widget que vous pouvez télécharger sur internet est compressé au format zip. Avant de l'utiliser, il est nécessaire de le décompresser. Si vous n'avez aucuns programmes permettant d'ouvrir les fichiers zip, vous pouvez télécharger 7zip sur http://www.7-zip.org/. GraphMe a été conçu pour s'utiliser dans un navigateur internet ou s'intégrer à Uniboard. Pour l'ajouter aux widgets d'Uniboard, il faut copier le dossier « GraphMe.wgt » dans « library/interactive/ ». Par exemple, sous Windows, le widget doit être dans : « C:/Program Files/Uniboard 4/library/interactive/GraphMe.wgt ». Si vous n'avez pas Uniboard, vous pouvez l'obtenir sur http://getuniboard.com/. -

+ This widget can be downloaded from the Internet in a packed format. Before using it must be unpacked. GraphMe was developed for using in web-browsers and integration in Sankore. To add this app in Sankore you should copy folder named "GraphMe.wgt" in "../library/interactive/". For example, on "windows OS" GraphMe must be in folder with following path: "C: / Program Files / Sankore 4/library/interactive/GraphMe.wgt". If you have no Sankore then you can get it on http://getuniboard.com/. +

-

3. Afficher le widget

-
Image de GraphMe dans un navigateur internet
+

3. Review widget

+
Display GraphMe in browsers

- A) Pour afficher le widget dans un navigateur, il faut simplement ouvrir le fichier « Grapheur.xhtml » qui se trouve dans le dossier « GraphMe.wgt » avec votre navigateur internet. Toutefois, certains navigateurs n'arrivent pas à afficher le widget. La liste suivante contient les navigateurs sur lesquels le widget a été testé : + A) To display this app in browser just enough to open the file named "Grapheur.xhtml" (it's in root folder) with your browser. But some browsers can not display app correctly. Below is the list of browsers that are able to display app:

    -
  • Mozilla Firefox (3.5) : tout fonctionne très bien.
  • -
  • Internet Explorer (8.0) : impossible d'ouvrir le widget, le format .xhtml n'est pas reconnu.
  • -
  • Internet Explorer (pré-version 9.0) : le widget est ouvrable mais seul l'affichage utilisant SVG fonctionne, « canvas » n'est toujours pas supporté.
  • -
  • Konqueror (4.3.4) : le widget s'ouvre mais il y a quelques problèmes d'affichage. Il est quand même utilisable en sélectionnant la méthode d'affichage « canvas » dans les options.
  • -
  • Opera (10.51) : le widget est parfaitement utilisable
  • -
  • Google Chrome (4.1) : tout fonctionne également. L'affichage 3D est même très rapide comparé à d'autres navigateurs.
  • +
  • Mozilla Firefox (3.5) : Everything works fine.
  • +
  • Internet Explorer (8.0) : Cannot open a widget, because .xhtml format is not recognized.
  • +
  • Internet Explorer (pré-version 9.0) : Widget works but just using SVG. Canvas not supported yet.
  • +
  • Konqueror (4.3.4) : Widget can be opened but there is some problems with displaying. It still occur when choosed display method "canvas".
  • +
  • Opera (10.51) : Widget quite useful.
  • +
  • Google Chrome (4.1) : Everything works very nice! 3D-display is faster as compared with other browsers.

- B) Pour ouvrir le widget dans Uniboard, il faut tout d'abord cliquer sur le bouton « Bibliothèque » en haut de la fenêtre. Ensuite, allez dans l'onglet « Interactif » ou autrement, selon les version d'Uniboard, dans l'onglet « Applications ». Cliquez sur l'icône correspondant à « Traceur de fonctions mathématiques » et finalement sur « Ajouter à la page ». + B) To open widget in Sankore you should first open folder "Application" that is at the left of the screen. Then you must find this app and add it to the page.

-
Image de GraphMe dans Uniboard
+
Display GraphMe in Sankore
-

4. Présentation de l'affichage

+

4. View presentation

    -
  1. Champ permettant de définir la fonction à afficher.
  2. -
  3. Bouton affichant la fonction.
  4. -
  5. Bouton servant à ajouter une nouvelle fonction ou à accéder à l'historique des fonctions.
  6. -
  7. Zone d'affichage.
  8. -
  9. Options d'affichage permettant de définir la partie de la fonction à afficher.
  10. -
  11. Boutons de zoom.
  12. -
  13. Bouton servant à changer la couleur.
  14. -
  15. Boutons accédant aux différents menus.
  16. -
  17. Onglet choisissant entre les fonctions 2D et 3D.
  18. -
  19. Bouton de maximisation du widget.
  20. +
  21. Place for functions display.
  22. +
  23. Button for beginning the work.
  24. +
  25. Button for adding new function or for getting access to functions history.
  26. +
  27. Display.
  28. +
  29. Parameters that define the part of graph that will be displayed.
  30. +
  31. Buttons for zoom.
  32. +
  33. Button for color changing.
  34. +
  35. Buttons for access to menu.
  36. +
  37. Tab-button that toggles 2D and 3D modes.
  38. +
  39. Button for maximize the widget.
-

5. Dessiner une fonction

+

5. Drawing the function

- Pour dessiner une fonction mathématique, il suffit d'entrer celle-ci dans le champ en haut du widget et de cliquer sur le bouton « Afficher ». On peut utiliser différentes fonctions et constantes prédéfinies: + To draw mathematical function just enter it at the top of widget and press button "Display". You can use different functions and predefined constants.

-

Les opérations de base

+

Basic operations:

    -
  • l'addition → +
  • -
  • la soustraction → -
  • -
  • la multiplication → *
  • -
  • la division → /
  • -
  • le modulo → %
  • +
  • Addition → +
  • +
  • Subtraction → -
  • +
  • Multiplication → *
  • +
  • Division → /
  • +
  • Mod → %
-

Les fonctions trigonométriques

+

Trigonometric functions

  • sin(x), cos(x), tan(x), cot(x)
  • asin(x), acos(x), atan(x), acot(x) ( ou arcsin(x), arccos(x), arctan(x), arccot(x) )
-

Les racines et les puissances

+

Square roots and degrees

    -
  • sqrt(x) fait la racine carrée de x
  • -
  • pow(x, y) élève un nombre x à une puissance y, par exemple :
    x² → pow(x, 2)
    (x+3)⁵ → pow((x+3), 5)
  • -
  • root(x, y) fait la racine yème d'un nombre x
  • +
  • sqrt(x) is square root from x
  • +
  • pow(x, y). Variable x to the power y. For examle:
    x² → pow(x, 2)
    (x+3)⁵ → pow((x+3), 5)
  • +
  • root(x, y). Root y of x
-

Les exponentielles et logarithmes

+

Exponential and logarithm

  • exp(x)
  • -
  • ln(x) est le logarithme naturel
  • -
  • log(x) est le logarithme de base 10
  • +
  • ln(x) is natural logarithm.
  • +
  • log(x) is decimal logarithm.
-

Les arrondis

+

Rounding

    -
  • round(x) → arrondit à l'entier le plus proche
  • -
  • ceil(x) → arrondit à l'entier supérieur
  • -
  • floor(x) → arrondit à l'entier inférieur
  • +
  • round(x) → rounding to the nearest whole number
  • +
  • ceil(x) → rounding to the nearest whole number in a big way
  • +
  • floor(x) → rounding to the nearest whole number the smaller side
-

Autres fonctions prédéfinies

+

Other predefined function

    -
  • abs(x) → la valeur absolue d'un nombre
  • -
  • random() → retourne un nombre aléatoire entre 0 et 1
  • +
  • abs(x) → Absolute number value
  • +
  • random() → Return random number between 0 and 1
-

Les constantes

+

Also are available some constants:

  • pi = 4 * atan(1) ≈ 3.141592653589793
  • e = exp(1) ≈ 2.718281828459045

- Il n'est pas toujours facile de comprendre comment écrire la fonction désirée. En effet, une petite faute et elle ne s'affichera pas. De plus, il ne faut pas oublier de mettre un « * » entre les thermes à multiplier et d'utiliser le point « . » pour écrire des nombres à virgule. + Not always it's easy to understand how to record a required function. Really if anywhere you err then graph will not displayed. Also do not forget about "*" (multiply) to multiply and "." (decimal point) to write point.

- Les fonctions en deux dimensions s'écrivent sous la forme : y=[...] et les fonctions en trois dimensions sous la forme : z=[...]. D'autres exemples sont disponibles dans le menu « aide » du widget si vous avez de la peine à entrer une fonction. + The two-dimensional function must be written as y=[...] and the three-dimensional function nust be written as z=[...]. Other examples are available to use in menu "Help" if you have some difficulties with function definition.

-

6. Se déplacer à travers la fonction

+

6. Offset function

- Parfois, lorsqu'on dessine une fonction, la zone visible n'est pas très intéressante. Pour cela, il est utile de déplacer l'affichage ou de définir soi-même la zone à afficher. + Sometimes when you draw the function you don't see all necessary information about this function. In this case you can change position of graph.

- Pour déplacer la fonction, il suffit d'utiliser les flèches de navigation situées dans les quatre bords de l'affichage ou l'outil de déplacement à la souris (dans le menu « Outils »). + To move the function graph just use a navigation arrows that are in the four edges of the display or mouse move tool (menu Service).

- Pour définir la zone à afficher, il faut entrer des valeurs personnalisées dans les champs à gauche du widget. La valeur de gauche doit obligatoirement être plus petite que la valeur de droite. Dans le cas contraire, la fonction ne se dessinera pas. + To define place to display you should enter a custom values in the left side of the widget. The left value must be less than the right value. In other case graph will not displayed.

- Il est possible de zoomer ou dé-zoomer l'affichage en utilisant les boutons du menu de gauche pour voir une plus grande partie de la fonction. Le zoom peut être réinitialisé dans les options. On peut également cliquer deux fois sur le graphique pour zoomer ainsi que dé-zoomer en maintenant la touche « ctrl » appuyée et en cliquant deux fois. + You can increase or decrease the scale of displaying using buttons that are in the left menu. So you'll see more information about function. Zoom can be reset in options.

- +

- Cliquez sur le bouton « Options » à gauche du widget pour ouvrir ce menu. En cliquant à nouveau sur le bouton, cela ferme le menu. Plusieurs onglets permettent de naviguer entre les différentes options. Description des options : + To open the menu you should click a button "Options" that is in the left of the widget. If you click on this button again then menu will close. There are some buttons for navigation between options. Their short description:

    -
  • Le thème du widget change l'image de fond ainsi que différentes couleurs. Dans Uniboard, changer le thème permet de rendre le widget plus visible selon qu'il se trouve sur un fond noir ou un fond blanc.
  • -
  • La méthode d'affichage permet de définir la façon dont le graphique de la fonction sera dessiné. Il y a le choix entre six possibilités :
    +
  • Changing a background image and color. In Sankore changing background theme used for displaying widget on black and white background.
  • +
  • Display-method used for defining displaying function. There are 6 possibilities:
      -
    1. SVG est un format d'image vectoriel qui peut être intégré dans une page HTML. Il est compatible dans la plupart des navigateurs Internet et est très bien supporté par Uniboard, c'est pourquoi il est choisi par défaut.
    2. -
    3. « SVG (une image) » ne présente que peu de différence avec la méthode d'affichage « SVG ». A moins d'un problème de compatibilité, il n'est pas très utile de la choisir.
    4. -
    5. Canvas est une nouvelle balise présente depuis HTML 5.0. Elle permet de définir une zone dans laquelle on peut faire des dessins. Cette méthode d'affichage est plus rapide que d'utiliser du SVG, cependant, elle n'est pas complètement compatible dans Uniboard. Il est conseillé de choisir cette option si vous utilisez le widget ailleurs que dans Uniboard.
    6. -
    7. Canvas (point) utilise aussi canvas, mais dessine des points à la place de lignes.
    8. -
    9. XPM est un format d'image très peu connu. De ce fait, il est compatible qu'avec une minorité de navigateur.
    10. -
    11. La méthode d'affichage « Uniboard » permet de dessiner directement sur la page d'Uniboard avec les outils de dessins.
    12. +
    13. SVG is a vector format of image and it can be built in HTML-page. It's compatible in most of browsers and Sankore support it very well so is it selected default.
    14. +
    15. There is a big difference between SVG (image) and display method SVG. If you have a compatibility problems then you should not use this method.
    16. +
    17. "Canvas" is a new tag that used in HTML 5.0. It define a area in which you can place some images. This display-method is faster than SVG-method, but Sankore does not fully support it. It's desirable to choose this method when you use no Sankore widget.
    18. +
    19. "Canvas" (point) also uses a canvas but draws a points instead of lines.
    20. +
    21. XPM format is little known so it's compatible just with a minority of browsers.
    22. +
    23. Display method "Uniboard" allows to draw directly on the page using Sankore drawing.
  • -
  • Le zoom par défaut ainsi que le bouton « réinitialiser le zoom » permettent de remettre l'affichage à l'état qu'il était à l'ouverture du widget. Cela permet aussi de centrer l'affichage sur l'origine.
  • -
  • Les options d'affichage permettent d'afficher ou non la grille, les axes ainsi que l'échelle. Elles sont utiles pour rendre l'affichage plus lisible. Il est également possible de modifier l'épaisseur du trait de la fonction.
  • -
  • Le décalage du graphique n'a en principe pas besoin d'être utilisé. Il permet de déplacer tout l'affichage dans un sens ou dans l'autre, s'il n'est pas centré à la bonne place. Cela peut arriver avec certains navigateurs Internet.
  • -
  • La précision des calculs du graphique permet d'augmenter ou de diminuer le nombre de points calculés. Plus le nombre est petit, plus la précision est grande. Il est utile de mettre cette valeur à « 0.01 » si vous dessinez des fonctions ressemblant à 0.5*sin(10*x*x).
  • -
  • Dans les options 3D, le style d'affichage permet de choisir comment la fonction est dessinée : avec des petits points ou avec des polygones (surfaces). La plupart des fonctions sont plus jolies en dessinant la surface entre les points calculés. Toutefois, c'est mieux de dessiner des points pour des fonctions comme la demi-sphère : sqrt(12-x*x-y*y).
  • -
  • Dans le dernier onglet, vous pouvez modifier d'autres options 3D, comme la précision des calculs ainsi que la couleur de la fonction.
  • +
  • Default zoom button returns display into original state. It helps alsoto return to the origin.
  • +
  • Display options allow to display or not a grid, axis and scale. They make a mapping more readable. Also you can change the thickness of function line.
  • +
  • Offset of graph not used usually. But if you use it then you can move a mapping in any direction when a center isn't in the right place. It's avaliable in some browsers.
  • +
  • The accuracy of calculations of the graph will increase or decrease the number of points calculated. The higher the number, the more accuracy. It is useful to set this value to "0.01" if you draw functions like 0.5 * sin (10 * x * x).
  • +
  • Options in 3D, the display style to choose how the function is designed: with small points or polygons (areas). Most functions are prettier drawing surface between the points calculated. However, it is better to draw points for functions such as the hemisphere: sqrt (12 - x*x - y*y).
  • +
  • In the last tab you can change such options 3D, as the accuracy of the calculations and the color of the function.
- +

- Ce menu permet tout d'abord de choisir l'action de la souris sur le graphique. Il y a le choix entre trois possibilités : + This menu allows you to choose first action of the mouse on the graph. There is a choice of three options:

    -
  • L'outil sélectionné par défaut est le point. En bougeant la souris, un point se déplace sur la fonction et les coordonnées de ce point sont indiquées en haut à gauche de l'affichage.
  • -
  • Le deuxième outil est le déplacement. Il permet de déplacer le graphique avec la souris. Il suffit de tenir cliqué sur l'affichage et de bouger la souris. Malheureusement, cet outil peut être lent sur certains navigateurs.
  • -
  • Le troisième outil est la tangente. Cet outil dessine la tangente à la fonction au point où se trouve la souris.
  • +
  • The selected tool is the default. By moving the mouse, a point moves on the function and the coordinates of this point are shown in the top left of the display.
  • +
  • The second tool is moving. It allows you to move the chart with the mouse. Just keep clicking on the display and move the mouse. Unfortunately, this tool can be slow on some browsers.
  • +
  • The third tool is the tangent. This tool draws the tangent to the function at the point where is a mouse cursor.

- Ensuite, ce menu permet aussi de calculer un point de la fonction. Il faut simplement entrer la coordonnée « x » du point dont on veut trouver la coordonnée « y », et appuyer sur le bouton « Évaluer ». Par exemple, si la fonction est « x*x » et qu'on défini « x=2 », alors le point dont la coordonnée sur l'axe des X est « 2 » aura comme coordonnée sur l'axe des Y « 4 ». + Then, this menu also allows to calculate a point of the function. Simply enter the coordinate "x" from the point where we want to find the coordinate "y" and press the "Evaluate". For example, if the function is "x * x" and that defined "x = 2", then the point whose coordinate on the X axis is "2" will be to coordinate on the Y axis "4".

- Un autre outil très utile est l'étude de fonction. Pour étudier la fonction entrée dans le champ en haut du widget, cliquez sur « démarrer l'étude ». Les études de fonction de ce widget ne sont pas fiables à 100% mais servent de complément à une étude de fonction que l'on fait soi-même. Il se peut que cet outil soit amélioré dans une prochaine version du widget. + Another useful tool is the analysis of function. To analyse the function click on "start the analysis". Analyses based on this widget are not 100% reliable, but are complementary to a analysis of function that you are doing yourself. It may be that this tool will be improved in a future version of the widget.

- Dans ce menu, on trouve également des tests d'affichage. Ils permettent d'essayer les différentes méthodes d'affichage et de voir si elles fonctionnent sur le navigateur internet utilisé. + In this menu there are also tests the display. They can try different methods to display and see if they work on the browser used.

-

9. Dessiner plusieurs fonctions

+

9. Drawing some functions

- Pour dessiner plusieurs fonctions simultanément, cliquez sur le petit bouton « + » qui se situe à droite du bouton « Afficher » (point 1). Ensuite, un menu apparaît. + To draw multiple functions simultaneously, click the small "+" button which is located to the right of "View" (point 1). Then, a menu appears.

- Dans ce menu, des onglets permettent d'aller à l'historique ou aux fonctions supplémentaires (point 2). Pour ajouter une fonction, cliquez sur le bouton à droite de la fonction actuelle (point 3). En dessous, une liste contient toutes les fonctions affichées (point 4). Pour supprimer une fonction, il faut simplement cliquer sur le bouton « - » à coté de celle-ci. Il est également possible de modifier la couleur de chaque fonction séparément. + The tabs in this menu can go to the history or the additional features (point 2). To add a function click the button to the right of the current function (point 3). Below is a list that contains all the displayed functions (point 4). To remove a function, just click on the "-" button next to it. It is also possible to change the color of each function separately.

- L'historique permet de revoir toutes les fonctions qui ont déjà été dessinées. Lorsque l'on clique sur une fonction de l'historique, celle qui est dessinée actuellement est remplacée par la fonction de l'historique. + History can review all the functions that have already been drawn. When you click on a function of history current function replaced by the function of history.

- Dessiner plusieurs fonctions simultanément est uniquement possible avec la méthode d'affichage « canvas » en deux dimensions. Par contre, l'historique est utilisable avec toutes les méthodes d'affichage. + "Drawing several functions simultaneously" mode is only possible with the display method "canvas" in two dimensions, but the history can be used with all methods of display.

-

10. Mettre à jour GraphMe

+

10. GraphMe update

- La dernière version du widget est téléchargeable sur la page suivante : http://gyb.educanet2.ch/tm-widgets/.ws_gen/?15. Pour mettre à jour GraphMe, vous pouvez aussi cliquer sur le bouton "Mise à jour" dans le menu des options. + The latest version of the widget can be downloaded from the following page: http://gyb.educanet2.ch/tm-widgets/.ws_gen/?15. To update GraphMe, you can also click on "Update" in the options menu.

11. Contact

- Si vous voulez rapporter un bug, avez une suggestion par rapport au widget ou voulez simplement poser une question, merci de me contacter par e-mail à l'adresse : yannick.vessaz@gmail.com. + If you want to report a bug, have a suggestion from the widget or just want to ask a question, please contact me by e-mail at: yannick.vessaz@gmail.com.

\ No newline at end of file diff --git a/resources/library/interactive/Graphme.wgt/JavaScript/AffichageUniboard.js b/resources/library/interactive/Graphme.wgt/JavaScript/AffichageUniboard.js index 6d03beca..d60ed141 100644 --- a/resources/library/interactive/Graphme.wgt/JavaScript/AffichageUniboard.js +++ b/resources/library/interactive/Graphme.wgt/JavaScript/AffichageUniboard.js @@ -1,5 +1,5 @@ -// -------------------- Uniboard -------------------- -// Ces fonctions permettent de dessiner le graphique directement dans Uniboard. +// -------------------- sankore -------------------- +// Ces fonctions permettent de dessiner le graphique directement dans sankore. // Calcule tous les points de la fonction mathématique et les place dans des tableaux. function evaluerUniboard(eq) { @@ -28,33 +28,33 @@ // Regarde chaque coordonnées stockées dans le tableau et dessine le graphique function calculerGraphUniboard(fin){ document.getElementById("affichage").innerHTML = "" - uniboard.setTool('pen') - uniboard.moveTo(pointX[2]+decalageX, pointY[2]+decalageY) + sankore.setTool('pen') + sankore.moveTo(pointX[2]+decalageX, pointY[2]+decalageY) for (i=3; ihauteur)){ - uniboard.moveTo(pointX[i+1]+decalageX,pointY[i+1]+decalageY) + sankore.moveTo(pointX[i+1]+decalageX,pointY[i+1]+decalageY) continue } - uniboard.drawLineTo(pointX[i]+decalageX, pointY[i]+decalageY, lineWidth) + sankore.drawLineTo(pointX[i]+decalageX, pointY[i]+decalageY, lineWidth) } //dessiner le cadre - uniboard.moveTo(0+decalageX,0+decalageY) - uniboard.drawLineTo(largeur+decalageX, 0+decalageY, lineWidth) - uniboard.drawLineTo(largeur+decalageX, hauteur+decalageY, lineWidth) - uniboard.drawLineTo(0+decalageX, hauteur+decalageY, lineWidth) - uniboard.drawLineTo(0+decalageX, 0+decalageY, lineWidth) + sankore.moveTo(0+decalageX,0+decalageY) + sankore.drawLineTo(largeur+decalageX, 0+decalageY, lineWidth) + sankore.drawLineTo(largeur+decalageX, hauteur+decalageY, lineWidth) + sankore.drawLineTo(0+decalageX, hauteur+decalageY, lineWidth) + sankore.drawLineTo(0+decalageX, 0+decalageY, lineWidth) //dessiner les axes - uniboard.moveTo((-borneXGauche*multiplicateurX)+decalageX, 0+decalageY) - uniboard.drawLineTo((-borneXGauche*multiplicateurX)+decalageX, hauteur+decalageY, lineWidth) - uniboard.moveTo(0+decalageX, (hauteur-(-borneYGauche*multiplicateurY))+decalageY) - uniboard.drawLineTo(largeur+decalageX, (hauteur-(-borneYGauche*multiplicateurY))+decalageY, lineWidth) + sankore.moveTo((-borneXGauche*multiplicateurX)+decalageX, 0+decalageY) + sankore.drawLineTo((-borneXGauche*multiplicateurX)+decalageX, hauteur+decalageY, lineWidth) + sankore.moveTo(0+decalageX, (hauteur-(-borneYGauche*multiplicateurY))+decalageY) + sankore.drawLineTo(largeur+decalageX, (hauteur-(-borneYGauche*multiplicateurY))+decalageY, lineWidth) decalageX += 250 decalageY += 200 largeur -= 100 hauteur -= 100 - uniboard.setTool('arrow') + sankore.setTool('arrow') } \ No newline at end of file diff --git a/resources/library/interactive/Graphme.wgt/JavaScript/Etude.js b/resources/library/interactive/Graphme.wgt/JavaScript/Etude.js index 104d503f..79e39bb4 100644 --- a/resources/library/interactive/Graphme.wgt/JavaScript/Etude.js +++ b/resources/library/interactive/Graphme.wgt/JavaScript/Etude.js @@ -136,13 +136,13 @@ function pariteFct(){ } } if(paire){ - document.getElementById("etudeParite").innerHTML = "paire" + document.getElementById("etudeParite").innerHTML = "even" } else if(impaire){ - document.getElementById("etudeParite").innerHTML = "impaire" + document.getElementById("etudeParite").innerHTML = "uneven" } else{ - document.getElementById("etudeParite").innerHTML = "aucune" + document.getElementById("etudeParite").innerHTML = "n/a" } } @@ -272,7 +272,7 @@ function signeFct(fct){ listeZeros.splice((aSupprimer[i]-i), 1) } if(listeZeros==""){ - texteZeros = "aucuns" + texteZeros = "n/a" } document.getElementById("etudeZeros").innerHTML = texteZeros+listeZeros } @@ -282,32 +282,32 @@ function asymptotes(){ if(Math.abs(limGauche[0])<1000){ var limRound = Math.round(limGauche[0]*100)/100 if(limGauche[0](courbe au-dessous de l'AH)" + document.getElementById("etudeAHG").innerHTML = "y = "+limRound +" (curve is higher than a l'AH)" } else if(limGauche[0]>limRound){ - document.getElementById("etudeAHG").innerHTML = "y = "+limRound +" (courbe au-dessus de l'AH)" + document.getElementById("etudeAHG").innerHTML = "y = "+limRound +" (curve is lower than a l'AH)" } else{ document.getElementById("etudeAHG").innerHTML = "y = "+limRound } } else{ - document.getElementById("etudeAHG").innerHTML = "aucune" + document.getElementById("etudeAHG").innerHTML = "n/a" } if(Math.abs(limDroite[0])<1000){ var limRound = Math.round(limDroite[0]*100)/100 if(limDroite[0](courbe au-dessous de l'AH)" + document.getElementById("etudeAHD").innerHTML = "y = "+limRound +" (curve is lower than a l'AH)" } else if(limDroite[0]>limRound){ - document.getElementById("etudeAHD").innerHTML = "y = "+limRound +" (courbe au-dessus de l'AH)" + document.getElementById("etudeAHD").innerHTML = "y = "+limRound +" (curve is higher than a l'AH)" } else{ document.getElementById("etudeAHD").innerHTML = "y = "+limRound } } else{ - document.getElementById("etudeAHD").innerHTML = "aucune" + document.getElementById("etudeAHD").innerHTML = "n/a" } // Verticales var texteAV = "" @@ -318,7 +318,7 @@ function asymptotes(){ } } if(texteAV==""){ - texteAV = "aucune
" + texteAV = "n/a
" } document.getElementById("etudeAV").innerHTML = texteAV } @@ -343,8 +343,8 @@ function courbure(){ } } } - if(texteMin==""){texteMin = "
Aucun Minimum";} - if(texteMax==""){texteMax = "
Aucun Maximum";} + if(texteMin==""){texteMin = "
No minimum";} + if(texteMax==""){texteMax = "
No maximum";} if(texteI==""){texteI = "
Aucun I";} document.getElementById("etudeMin").innerHTML = texteMin; document.getElementById("etudeMax").innerHTML = texteMax; diff --git a/resources/library/interactive/Graphme.wgt/JavaScript/Interface.js b/resources/library/interactive/Graphme.wgt/JavaScript/Interface.js index fd393f69..34a1bef2 100644 --- a/resources/library/interactive/Graphme.wgt/JavaScript/Interface.js +++ b/resources/library/interactive/Graphme.wgt/JavaScript/Interface.js @@ -28,7 +28,7 @@ function cacherMenu(){ menuActuel = "" } -// ---- Minimiser ou Maximiser le widget (pour Uniboard) ---- +// ---- Minimiser ou Maximiser le widget (pour sankore) ---- function miniMax(){ if (maximise){ maximise = false @@ -99,7 +99,7 @@ function changerTheme(){ // Affiche un message d'erreur function error(err){ - alert(" Erreur sur la page...\n\n Description: " + err.description + "\n\n Cliquez sur OK pour continuer.\n\n") + alert(" Error has occurred on the page ...\n\n Description: " + err.description + "\n\n Click 'OK' to continue.\n\n") } diff --git a/resources/library/interactive/Graphme.wgt/JavaScript/Sauvegardes.js b/resources/library/interactive/Graphme.wgt/JavaScript/Sauvegardes.js index 22cab044..b9f6cf10 100644 --- a/resources/library/interactive/Graphme.wgt/JavaScript/Sauvegardes.js +++ b/resources/library/interactive/Graphme.wgt/JavaScript/Sauvegardes.js @@ -88,7 +88,7 @@ function loadOptions(){ } else{ if(document.cookie!=""){ - alert("Impossible de charger les options enregistrées..."); + alert("It's can't be downloaded ..."); } } } @@ -115,5 +115,5 @@ function checkOptions(){ } function alertOptions(){ - alert("Options actuellement sauvegardées\n------------------------------------------------------------\n"+document.cookie); + alert("Now parameters will be saved\n------------------------------------------------------------\n"+document.cookie); } \ No newline at end of file diff --git a/resources/library/interactive/iCell.wgt/js/textes_descriptifs.js b/resources/library/interactive/iCell.wgt/js/textes_descriptifs.js index 9e54de32..4daaedaa 100644 --- a/resources/library/interactive/iCell.wgt/js/textes_descriptifs.js +++ b/resources/library/interactive/iCell.wgt/js/textes_descriptifs.js @@ -1,63 +1,63 @@ -/* Pour info, les span taient une tentative de mise en forme via CSS mais j'ai trouv plus pratique, et je les ai laisss au cas o... */ +/* Pour info, les span йtaient une tentative de mise en forme via CSS mais j'ai trouvй plus pratique, et je les ai laissйs au cas oщ... */ - var txt_vesicule = "

Vsicule
Transporteurs

"+ - "

Structure:

Bicouche phospholipidique

"+ - "

Rle:

Transport de protines ou d'autres lments l'intrieur de la cellule, vers l'extrieur (exocytose) ou vers l'intrieur (endocytose).

"+ - '

Fonctionnement:

Transporteur "remorqu" par des protines prenant appui sur le cytosquelette.

' + var txt_vesicule = "

Vesicle
Transporter

"+ + "

Structure:

Phospholipid bilayer

"+ + "

Role:

Transport of proteins and other components inside the cell to the exterior (exocytosis) or inward (endocytosis).

"+ + '

Operation:

Transport "towed" by Protein building on the cytoskeleton.

' - var txt_lysosome = "

Lysosome
Estomacs cellulaires

"+ - "

Structure:

Bicouche phospholipidique

"+ - "

Rle:

Digestion intra-cellulaire l'aide d'enzymes

"+ - "

Fonctionnement:

Absorption de nutriments par endocytose ou d'lments cellulaires abims, digestion de ceux-ci, puis distribution des rsultats de la raction chimique dans la cellule et enfin expulsion des dchets par exocytose.

" + var txt_lysosome = "

Lysosome
A stomach cell.

"+ + "

Structure:

Phospholipid bilayer

"+ + "

Role:

А intracellular digestion with enzymes.

"+ + "

Operation:

Absorbes nutrient uptake or damaged cellular components by endocytosis, digest them and then distributes the results of the chemical reaction in the cell and finally expels of waste by exocytosis.

" - var txt_mitoch = "

Mitochondrie
Piles

"+ - "

Structure:

Deux bichouches phospholipidiques appeles membranes mitochondriales, une externe et une interne. La mitochondrie contient des ribosomes, de l'ATP de l'ADN et bien d'autres molcules.

"+ - "

Rle:

Centrale nergtique de la cellule.

"+ - "

Fonctionnement:

L'nergie - sous forme d'ATP (adnosine triphosphate) - est issue de diffrentes tapes de ractions chimique partant d'une molcule de glucose.

" + var txt_mitoch = "

Mitochondrie
Batteries

"+ + "

Structure:

Two phospholipid bilayers called mitochondrial membranes, one external and one internal. The mitochondria contain ribosomes, ATP of DNA and other molecules.

"+ + "

Role:

Powerhouse of the cell.

"+ + "

Operation:

Energy - in the form of ATP (adenosine triphosphate) - comes from various stages of chemical reactions starting from a glucose molecule.

" - var txt_golgi = "

Appareil de Golgi
Usines miniatures

"+ - "

Structure:

Form d'un empilement de saccules membranaires applatis.

"+ - "

Rle:

Modification de certaines protines au cours d'un cheminement au travers de ses saccules.

"+ - "

Fonctionnement:

Suite de ractions chimiques, notamment par glycosilation.

" + var txt_golgi = "

Apparatus golgi
Miniature plants

"+ + "

Structure:

Has a stack of flattened membrane saccules.

"+ + "

Role:

Modification of proteins during a journey through its saccules.

"+ + "

Operation:

Chemical reactions, including glycosylation.

" - var txt_rer = "

Rticulum endoplasmique rugueux - Tunnel

"+ - "

Structure:

Compos d'une bicouche phospholipidique piquete de ribosomes (d'un aspect rugueux) dlimitant la lumire, un espace interne pouvant tre compar un tunnel.

"+ - "

Rle:

Plus spcialis que le REL, il participe au transport et la finalisation des protines, qui sont synthtises par les ribosomes.

"+ - '

Fonctionnement:

Les protines "tombent" dans la lumire du RER o elles sont modifies et dplaces. Elles quittent le RER dans une vsucule issue de la membrane de ce dernier.

' + var txt_rer = "

Rough endoplasmic reticulum - Tunnel

"+ + "

Structure:

Consists of a phospholipid bilayer studded with ribosomes (an aspect rough ) define the light, an internal space that can be compared to a tunnel.

"+ + "

Role:

More specialized than the real, he participated in the transport and а finalizing the proteins that are synthesized by ribosomes.

"+ + '

Operation:

Proteins "fall" in the light of the RER where they are modified and displaced. They leave the RER in a vesicle membrane after it.

' - var txt_noy = "

Noyau - Le coffre-fort

"+ - "

Structure:

Entour par une double membrane appele enveloppe nuclaire en lien par endroits avec le RER. Ces deux membranes fusionnent intervalles rguliers pour former les pores nuclaires. l'intrieur se trouvent le nuclole et l'ADN, sous forme de chromatine ou de chomosomes.

"+ - "

Rle:

Stockage de la totalit des informations gntiques ncessaires la vie de la cellule.

"+ - "

Fonctionnement:

Site de la transcription (copie de l'information gntique sur des ARNm).

" + var txt_noy = "

Core - The safe

"+ + "

Structure:

Surrounded by a double membrane, that called the nuclear envelope, in places linked with the RER. These two membranes protect regular intervals formed nuclear pores. It located within the nucleolus and the DNA in the form of chromatin or chromosomes.

"+ + "

Role:

Storing all the genetic information necessary for a life of the cell.

"+ + "

Operation:

Copying of genetic information on mRNA.

" - var txt_rel = "

Rticulum endoplasmique lisse - REL

"+ - "

Structure:

Similaires celle du RER, la diffrence que sa membranne n'est pas parseme de ribosomes, d'o son aspect lisse.

"+ - "

Rle:

Sinthse des phospholipides,stockage du calcium, transformation de certaines molcules extrieures (mdicament, alcool, ...). Dans certaines cellules, le REL remplit aussi des fonctions supplmentaires, telles la production d'hormones, d'acides gastriques, etc.

"+ - "

Fonctionnement:

Il est le sige de beaucoup de ractions chimiques complexes (ex: dtoxification, diffrentes synthses).

" + var txt_rel = "

Smooth endoplasmic reticulum - REL

"+ + "

Structure:

Like that of the RER, with the difference that the membrane is studded with ribosomes, as its smooth appearance.

"+ + "

Role:

Phospholipid synthesis, calcium storage, transformation of certain molecules external (drugs, alcohol, ...). In some cells, the LRA also performs additional functions, such as the production of hormones, gastric acid, etc.

"+ + "

Operation:

It is the seat of many complex chemical reactions (eg detoxification, various syntheses).

" - var txt_adn = "

ADN - Le livre de la vie

"+ - "

Structure:

chelle la clbre forme de double hlice compose de deux colonnes sucre-phosphate-sucre-phosphate-... et dont les chelons sont apells bases azotes.

"+ - "

Rle:

L'ADN contient toutes les informations ncessaires la vie.

"+ - "

Fonctionnement:

Toutes les informations sont crites l'aide des quatre lettres A, T, G, et C. Grce ces combinaisons, il est possible d'crire tout ce qui est utile la cellule.

" + var txt_adn = "

DNA - The Book of Life

"+ + "

Structure:

A scale in form of the famous double helix consists of two columns sugar-phosphate-sugar-phosphate ... and whose levels are called nitrogenous bases.

"+ + "

Role:

DNA contains all the information needed for a life.

"+ + "

Operation:

All information is written using the four letters A, T, G and C. Using these combinations, it is possible to write anything useful about cell.

" - var txt_centr= "

Centrioles - Remorqueurs de choromosomes

"+ - "

Structure:

Neuf triplets de microtubules entours par un certain nombre de protines.

"+ - "

Rle:

Sparer les diffrents chromosomes durant la division cellulaire.

"+ - "

Fonctionnement:

Les centrioles, une fois placs aux deux ples de la cellule, dploient des microtubules vers les centromres des chromosomes et les tirent vers eux pour les sparer.

" + var txt_centr= "

Centrioles - Tug of chromosomes

"+ + "

Structure:

Nine triplets of microtubules surrounded by a some number of proteins.

"+ + "

Role:

Separate the different chromosomes during cell division.

"+ + "

Operation:

Centrioles, once placed at the two poles of the cell, deploy the microtubules to the centromeres of chromosomes and pull them to them to separate them.

" - var txt_rib = "

Ribosome - Dcodeurs

"+ - "

Structure:

Form par deux sous-units composes d'ARN ribosomique et de protines.

"+ - "

Rle:

Le ribosome synthtise les protines.

"+ - "

Fonctionnement:

Un brin d'ARNm (messager) passe dans le ribosome et un ARNt (de transfert) entre dans la grande sous-unit si son codon (groupe de trois bases azotes) correspond celui qui est en face sur l'ARNm. Cet ARNt porte avec lui un acide amin spcifique qui est ajout la chaine dja assemble.

" + var txt_rib = "

Ribosome - Decoders

"+ + "

Structure:

Formed by two subunits composed of ribosomal RNA and proteins.

"+ + "

Role:

The ribosome synthesizes proteins.

"+ + "

Operation:

A strand of mRNA (messenger) pass through the ribosome and tRNA (transfer) between the large subunit where the codon (group of three nitrogen bases) is one who is in front of the mRNA. This tRNA carries with it a specific amino acid that is added а chain already assembled.

" - var txt_arn = "

ARN - Multifonction

"+ - "

Structure:

Trs similaire l'ADN la diffrence qu'il ne possde qu'un brin et que la thymine (T) de l'ADN est remplace par l'uracile (U). De plus, il est chimiquement plus instable que l'ADN, c'est pourquoi il n'est pas utilis pour le stockage d'informations long terme.

"+ - "

Rle:

Multiples, il existe des ARN de transport, messagers, rgulateus, guides, satellites, ...

"+ - "

Fonctionnement:

La copie d'informations gntiques se fait grce l'ouverture de la double-hlice d'ADN, puis la copie des codons sur l'ARN. Celui-ci peut alors sortir du noyau, ce que l'ADN ne peut pas faire.

" + var txt_arn = "

RNA - Multifunction

"+ + "

Structure:

Very similar DNA with the difference it has only one strand and thymine (T) of DNA is replaced by uracil (U). In addition, it is chemically more stable than DNA, so it is not used for information storage, just if in long term.

"+ + "

Role:

Multiple, there are RNA transport, passenger, cruise, guides, satellite ...

"+ + "

Operation:

Copying of genetic information, the opening of the double helix of DNA, and then copying the RNA codons. It can then exit the nucleus, the DNA can not do it.

" - var txt_nucl = "

Nuclole - Fabrique d'ARN

"+ - "

Structure:

Compos d'aucune membranne, c'est un agglomrat de protines et d'ARN.

"+ - "

Rle:

Lieu de la transcription d'ARN, nottament d'ARNr (ribosomiques) qui, associs avec des protines, vont former les deux sous-units des ribosomes.

"+ - "

Fonctionnement:

Cration d'un ribosome: Transcription des ARNr ainsi que des protines ncessaires (cette tape est effectue dans le cytoplasme par d'autres ribosomes) qui rentrent dans le noyau, association des molcules frachement formes en un nouveau ribosome, qui sort du noyau pour jouer son rle.

" + var txt_nucl = "

Nucleolus - Factory RNA

"+ + "

Structure:

Composed of any membrane, a cluster of proteins and RNA.

"+ + "

Role:

Location of the RNA transcripts, including RNA (ribosomal), which combines with protein, will form the two subunits of ribosomes.

"+ + "

Operation:

Creation of a ribosome: Transcription of rRNA and protein needed (this step is performed in the cytoplasm by other ribosomes) that fall within the nucleus, association of molecules frankly formed a new ribosome, which leaves the nucleus to play its role.

" \ No newline at end of file diff --git a/src/adaptors/UBImportPDF.cpp b/src/adaptors/UBImportPDF.cpp index 2a0811d8..b178b154 100644 --- a/src/adaptors/UBImportPDF.cpp +++ b/src/adaptors/UBImportPDF.cpp @@ -61,7 +61,7 @@ bool UBImportPDF::addFileToDocument(UBDocumentProxy* pDocument, const QFile& pFi QString filepath = UBPersistenceManager::persistenceManager()->addPdfFileToDocument(pDocument, pFile.fileName(), uuid); - PDFRenderer *pdfRenderer = PDFRenderer::rendererForUuid(uuid, pDocument->persistencePath() + "/" + filepath); // renderer is automatically deleted when not used anymore + PDFRenderer *pdfRenderer = PDFRenderer::rendererForUuid(uuid, pDocument->persistencePath() + "/" + filepath, true); // renderer is automatically deleted when not used anymore if (!pdfRenderer->isValid()) { diff --git a/src/adaptors/adaptors.pri b/src/adaptors/adaptors.pri index 7dd7104e..7f20116b 100644 --- a/src/adaptors/adaptors.pri +++ b/src/adaptors/adaptors.pri @@ -17,7 +17,6 @@ HEADERS += src/adaptors/UBExportAdaptor.h\ src/adaptors/UBCFFSubsetAdaptor.h HEADERS += src/adaptors/publishing/UBDocumentPublisher.h \ - src/adaptors/publishing/UBCapturePublisher.h \ src/adaptors/publishing/UBAbstractPublisher.h \ src/adaptors/publishing/UBSvgSubsetRasterizer.h @@ -42,7 +41,6 @@ SOURCES += src/adaptors/UBExportAdaptor.cpp\ src/adaptors/UBCFFSubsetAdaptor.cpp SOURCES += src/adaptors/publishing/UBDocumentPublisher.cpp \ - src/adaptors/publishing/UBCapturePublisher.cpp \ src/adaptors/publishing/UBAbstractPublisher.cpp \ src/adaptors/publishing/UBSvgSubsetRasterizer.cpp diff --git a/src/adaptors/publishing/UBCapturePublisher.cpp b/src/adaptors/publishing/UBCapturePublisher.cpp deleted file mode 100644 index 7405619f..00000000 --- a/src/adaptors/publishing/UBCapturePublisher.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#include "UBCapturePublisher.h" - -#include "frameworks/UBStringUtils.h" - -#include "core/UBApplication.h" -#include "core/UBSettings.h" - -#include "gui/UBMainWindow.h" - -#include "board/UBBoardController.h" - -#include "network/UBServerXMLHttpRequest.h" -#include "network/UBNetworkAccessManager.h" - -#include "domain/UBGraphicsScene.h" - -#include "core/memcheck.h" - -UBCapturePublisher::UBCapturePublisher(const QPixmap& pixmap, QObject *parent) - : UBAbstractPublisher(parent) - , mPixmap(pixmap) -{ - connect(this, SIGNAL(authenticated(const QUuid&, const QString&)) - , this, SLOT(postPixmap(const QUuid&, const QString&))); -} - - -void UBCapturePublisher::publish() -{ - UBAbstractPublisher::authenticate(); -} - - -void UBCapturePublisher::postPixmap(const QUuid& tokenUuid, const QString& encryptedBase64Token) -{ - UBCapturePublishingDialog dialog(UBApplication::mainWindow); - - QString defaultEMail = UBSettings::settings()->uniboardWebEMail->get().toString(); - dialog.email->setText(defaultEMail); - - QString defaultAuthor = UBSettings::settings()->uniboardWebAuthor->get().toString(); - dialog.author->setText(defaultAuthor); - - if (dialog.exec() == QDialog::Accepted) - { - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - UBApplication::showMessage(tr("Preparing capture for upload..."), true); - - QString title = dialog.title->text(); - QString description = dialog.description->toPlainText(); - QString email = dialog.email->text(); - QString author = dialog.author->text(); - - QPixmap pix(mPixmap); - - if (mPixmap.hasAlpha()) - { - if (UBApplication::boardController->activeScene()->isDarkBackground()) - pix.fill(Qt::black); - else - pix.fill(Qt::white); - - QPainter p(&pix); - p.drawPixmap(0, 0, mPixmap); - } - - QByteArray bytes; - QBuffer buffer(&bytes); - buffer.open(QIODevice::WriteOnly); - pix.save(&buffer, "JPG", 80); - buffer.close(); - - QUrl publishingEndpoint = QUrl(UBSettings::settings()->capturesPublishingUrl); - - mPublishImageOnWebUploadRequest = new UBServerXMLHttpRequest(UBNetworkAccessManager::defaultAccessManager() - , "application/octet-stream"); - - mPublishImageOnWebUploadRequest->setVerbose(true); - - connect(mPublishImageOnWebUploadRequest, SIGNAL(finished(bool, const QByteArray&)), this, SLOT(publishImageOnWebUploadResponse(bool, const QByteArray&))); - - mWebUploadPublishingUuid = QUuid::createUuid(); - - mPublishImageOnWebUploadRequest->addHeader("Publishing-UUID", UBStringUtils::toCanonicalUuid(mWebUploadPublishingUuid)); - mPublishImageOnWebUploadRequest->addHeader("Document-Title", title); - mPublishImageOnWebUploadRequest->addHeader("Document-Author", author); - mPublishImageOnWebUploadRequest->addHeader("Document-AuthorEMail", email); - mPublishImageOnWebUploadRequest->addHeader("Document-Description", description); - mPublishImageOnWebUploadRequest->addHeader("Deletion-Token", UBStringUtils::toCanonicalUuid(QUuid::createUuid())); - mPublishImageOnWebUploadRequest->addHeader("Token-UUID", UBStringUtils::toCanonicalUuid(tokenUuid)); - mPublishImageOnWebUploadRequest->addHeader("Token-Encrypted", encryptedBase64Token); - - mPublishImageOnWebUploadRequest->post(publishingEndpoint, bytes); - } - else - { - UBApplication::showMessage(tr("Publication canceled ...")); - QApplication::restoreOverrideCursor(); - } -} - - -void UBCapturePublisher::publishImageOnWebUploadResponse(bool success, const QByteArray& payload) -{ - QUrl url(QString::fromUtf8(payload)); - - if (success && url.isValid()) - { - UBApplication::showMessage(tr("Capture Published to the Web.")); - } - else - { - UBApplication::showMessage(tr("Error Publishing Capture to the Web: %1").arg(QString::fromUtf8(payload))); - } - - if (mPublishImageOnWebUploadRequest) - { - mPublishImageOnWebUploadRequest->deleteLater(); - mPublishImageOnWebUploadRequest = 0; - } - - QApplication::restoreOverrideCursor(); -} - - -UBCapturePublishingDialog::UBCapturePublishingDialog(QWidget *parent) - : QDialog(parent) -{ - Ui::capturePublishingDialog::setupUi(this); - - connect(dialogButtons, SIGNAL(accepted()), this, SLOT(accept())); - connect(dialogButtons, SIGNAL(rejected()), this, SLOT(reject())); - - connect(title, SIGNAL(textChanged(const QString&)), this, SLOT(updateUIState(const QString&))); - connect(email, SIGNAL(textChanged(const QString&)), this, SLOT(updateUIState(const QString&))); - - dialogButtons->button(QDialogButtonBox::Ok)->setEnabled(false); - dialogButtons->button(QDialogButtonBox::Ok)->setText(tr("Publish")); -} - - -void UBCapturePublishingDialog::updateUIState(const QString& string) -{ - Q_UNUSED(string); - - bool ok = title->text().length() > 0 - && email->text().length() > 0; - - dialogButtons->button(QDialogButtonBox::Ok)->setEnabled(ok); -} diff --git a/src/adaptors/publishing/UBCapturePublisher.h b/src/adaptors/publishing/UBCapturePublisher.h deleted file mode 100644 index bc7575d2..00000000 --- a/src/adaptors/publishing/UBCapturePublisher.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef UBCAPTUREPUBLISHER_H -#define UBCAPTUREPUBLISHER_H - -#include - -#include "ui_capturePublishing.h" - -#include "UBAbstractPublisher.h" - -class UBServerXMLHttpRequest; - -class UBCapturePublisher : public UBAbstractPublisher -{ - Q_OBJECT - - public: - explicit UBCapturePublisher(const QPixmap& pixmap, QObject *parent = 0); - - void publish(); - - private slots: - - void publishImageOnWebUploadResponse(bool success, const QByteArray& payload); - void postPixmap(const QUuid& tokenUuid, const QString& encryptedBase64Token); - - private: - - UBServerXMLHttpRequest *mPublishImageOnWebUploadRequest; - QUuid mWebUploadPublishingUuid; - QPixmap mPixmap; - -}; - -class UBCapturePublishingDialog : public QDialog, public Ui::capturePublishingDialog -{ - Q_OBJECT; - - public: - UBCapturePublishingDialog(QWidget *parent = 0); - ~UBCapturePublishingDialog(){} - - private slots: - void updateUIState(const QString& string); - -}; - -#endif // UBCAPTUREPUBLISHER_H diff --git a/src/board/UBBoardPaletteManager.cpp b/src/board/UBBoardPaletteManager.cpp index 9ce06f63..1e00c4e1 100644 --- a/src/board/UBBoardPaletteManager.cpp +++ b/src/board/UBBoardPaletteManager.cpp @@ -1,8 +1,16 @@ /* - * UBBoardPaletteManager.cpp + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * Created on: 3 nov. 2009 - * Author: Luc + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ #include "UBBoardPaletteManager.h" @@ -46,8 +54,6 @@ #include "tools/UBToolsManager.h" -#include "adaptors/publishing/UBCapturePublisher.h" - #include "UBBoardController.h" #include "core/memcheck.h" @@ -155,7 +161,6 @@ void UBBoardPaletteManager::setupPalettes() addItemActions << UBApplication::mainWindow->actionAddItemToCurrentPage; addItemActions << UBApplication::mainWindow->actionAddItemToNewPage; addItemActions << UBApplication::mainWindow->actionAddItemToLibrary; - addItemActions << UBApplication::mainWindow->actionShareItemOnWeb; mAddItemPalette = new UBActionPalette(addItemActions, Qt::Horizontal, 0); mAddItemPalette->setButtonIconSize(QSize(128, 128)); @@ -309,7 +314,6 @@ void UBBoardPaletteManager::connectPalettes() connect(UBApplication::mainWindow->actionAddItemToCurrentPage, SIGNAL(triggered()), this, SLOT(addItemToCurrentPage())); connect(UBApplication::mainWindow->actionAddItemToNewPage, SIGNAL(triggered()), this, SLOT(addItemToNewPage())); connect(UBApplication::mainWindow->actionAddItemToLibrary, SIGNAL(triggered()), this, SLOT(addItemToLibrary())); - connect(UBApplication::mainWindow->actionShareItemOnWeb, SIGNAL(triggered()), this, SLOT(shareItemOnWeb())); connect(UBApplication::mainWindow->actionEraseItems, SIGNAL(triggered()), mErasePalette, SLOT(close())); connect(UBApplication::mainWindow->actionEraseAnnotations, SIGNAL(triggered()), mErasePalette, SLOT(close())); @@ -573,27 +577,27 @@ void UBBoardPaletteManager::addItemToLibrary() mAddItemPalette->hide(); } -void UBBoardPaletteManager::shareItemOnWeb() -{ - QPixmap pixmap = mPixmap; +//void UBBoardPaletteManager::shareItemOnWeb() +//{ +// QPixmap pixmap = mPixmap; - if(mPixmap.isNull()) - { - pixmap = QPixmap(mItemUrl.toLocalFile()); - } +// if(mPixmap.isNull()) +// { +// pixmap = QPixmap(mItemUrl.toLocalFile()); +// } - if(!pixmap.isNull()) - { - UBCapturePublisher* publisher = new UBCapturePublisher(pixmap, this); - publisher->publish(); - } - else - { - UBApplication::showMessage(tr("Error Publishing Image to the Web")); - } +// if(!pixmap.isNull()) +// { +// UBCapturePublisher* publisher = new UBCapturePublisher(pixmap, this); +// publisher->publish(); +// } +// else +// { +// UBApplication::showMessage(tr("Error Publishing Image to the Web")); +// } - mAddItemPalette->hide(); -} +// mAddItemPalette->hide(); +//} void UBBoardPaletteManager::zoomButtonPressed() diff --git a/src/board/UBBoardPaletteManager.h b/src/board/UBBoardPaletteManager.h index d609604c..3226d7b9 100644 --- a/src/board/UBBoardPaletteManager.h +++ b/src/board/UBBoardPaletteManager.h @@ -118,7 +118,6 @@ class UBBoardPaletteManager : public QObject void addItemToCurrentPage(); void addItemToNewPage(); void addItemToLibrary(); - void shareItemOnWeb(); void purchaseLinkActivated(const QString&); diff --git a/src/board/UBBoardView.cpp b/src/board/UBBoardView.cpp index 295858c7..7e9a256b 100644 --- a/src/board/UBBoardView.cpp +++ b/src/board/UBBoardView.cpp @@ -13,882 +13,882 @@ * along with this program. If not, see . */ - -#include "UBBoardView.h" - -#include - -#include "UBDrawingController.h" - -#include "frameworks/UBGeometryUtils.h" - -#include "core/UBSettings.h" -#include "core/UBMimeData.h" -#include "core/UBApplication.h" -#include "core/UBSetting.h" -#include "core/UBPersistenceManager.h" - -#include "network/UBHttpGet.h" - -#include "gui/UBStylusPalette.h" -#include "gui/UBRubberBand.h" -#include "gui/UBToolWidget.h" -#include "gui/UBResources.h" -#include "gui/UBMainWindow.h" - -#include "board/UBBoardController.h" - -#include "domain/UBGraphicsTextItem.h" -#include "domain/UBGraphicsPixmapItem.h" -#include "domain/UBGraphicsWidgetItem.h" -#include "domain/UBItem.h" - -#include "document/UBDocumentProxy.h" -#include "../gui/UBThumbnailWidget.h" - -#include "frameworks/UBPlatformUtils.h" - -#include "core/memcheck.h" - -UBBoardView::UBBoardView (UBBoardController* pController, QWidget* pParent) -: QGraphicsView (pParent) -, mController (pController) -, mIsCreatingTextZone (false) -, mIsCreatingSceneGrabZone (false) -{ - init (); - - mFilterZIndex = false; -} - -UBBoardView::UBBoardView (UBBoardController* pController, int pStartLayer, int pEndLayer, QWidget* pParent) -: QGraphicsView (pParent) -, mController (pController) -{ - init (); - - mStartLayer = pStartLayer; - mEndLayer = pEndLayer; - - mFilterZIndex = true; -} - -UBBoardView::~UBBoardView () { - //NOOP -} - -void -UBBoardView::init () -{ - connect (UBSettings::settings ()->boardPenPressureSensitive, SIGNAL (changed (QVariant)), - this, SLOT (settingChanged (QVariant))); - - connect (UBSettings::settings ()->boardMarkerPressureSensitive, SIGNAL (changed (QVariant)), - this, SLOT (settingChanged (QVariant))); - - connect (UBSettings::settings ()->boardUseHighResTabletEvent, SIGNAL (changed (QVariant)), - this, SLOT (settingChanged (QVariant))); - - setWindowFlags (Qt::FramelessWindowHint); - setFrameStyle (QFrame::NoFrame); - setRenderHints (QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing); - setVerticalScrollBarPolicy (Qt::ScrollBarAlwaysOff); - setHorizontalScrollBarPolicy (Qt::ScrollBarAlwaysOff); - setAcceptDrops (true); - - setOptimizationFlag (QGraphicsView::IndirectPainting); // enable UBBoardView::drawItems filter - - mTabletStylusIsPressed = false; - mMouseButtonIsPressed = false; - mPendingStylusReleaseEvent = false; - - setCacheMode (QGraphicsView::CacheBackground); - - mUsingTabletEraser = false; - mIsCreatingTextZone = false; - mRubberBand = 0; - - mVirtualKeyboardActive = false; - - settingChanged (QVariant ()); - - unsetCursor(); -} - -UBGraphicsScene* -UBBoardView::scene () -{ - return qobject_cast (QGraphicsView::scene ()); -} - -void -UBBoardView::hideEvent (QHideEvent * event) -{ - Q_UNUSED (event); - emit hidden (); -} - -void -UBBoardView::showEvent (QShowEvent * event) -{ - Q_UNUSED (event); - emit shown (); -} - -void -UBBoardView::keyPressEvent (QKeyEvent *event) -{ - // send to the scene anyway - QApplication::sendEvent (scene (), event); - - if (!event->isAccepted ()) - { - switch (event->key ()) - { - case Qt::Key_Up: - case Qt::Key_PageUp: - case Qt::Key_Left: - { - mController->previousScene (); - break; - } - - case Qt::Key_Down: - case Qt::Key_PageDown: - case Qt::Key_Right: - case Qt::Key_Space: - { - mController->nextScene (); - break; - } - - case Qt::Key_Home: - { - mController->firstScene (); - break; - } - case Qt::Key_End: - { - mController->lastScene (); - break; - } - case Qt::Key_Insert: - { - mController->addScene (); - break; - } - } - - - if (event->modifiers () & Qt::ControlModifier) // keep only ctrl/cmd keys - { - switch (event->key ()) - { - case Qt::Key_Plus: - case Qt::Key_I: - { - mController->zoomIn (); - event->accept (); - break; - } - case Qt::Key_Minus: - case Qt::Key_O: - { - mController->zoomOut (); - event->accept (); - break; - } - case Qt::Key_0: - { - mController->zoomRestore (); - event->accept (); - break; - } - case Qt::Key_Left: - { - mController->handScroll (-100, 0); - event->accept (); - break; - } - case Qt::Key_Right: - { - mController->handScroll (100, 0); - event->accept (); - break; - } - case Qt::Key_Up: - { - mController->handScroll (0, -100); - event->accept (); - break; - } - case Qt::Key_Down: - { - mController->handScroll (0, 100); - event->accept (); - break; - } - default: - { - // NOOP - } - } - } - } -} - -bool -UBBoardView::event (QEvent * e) -{ - if (e->type () == QEvent::Gesture) - { - QGestureEvent *gestureEvent = dynamic_cast (e); - if (gestureEvent) - { - QSwipeGesture* swipe = dynamic_cast (gestureEvent->gesture (Qt::SwipeGesture)); - - if (swipe) - { - if (swipe->horizontalDirection () == QSwipeGesture::Left) - { - mController->previousScene (); - gestureEvent->setAccepted (swipe, true); - } - - if (swipe->horizontalDirection () == QSwipeGesture::Right) - { - mController->nextScene (); - gestureEvent->setAccepted (swipe, true); - } - } - } - } - - return QGraphicsView::event (e); -} - -void -UBBoardView::tabletEvent (QTabletEvent * event) -{ - if (!mUseHighResTabletEvent) - { - event->setAccepted (false); - return; - } - - UBDrawingController *dc = UBDrawingController::drawingController (); - - QPointF tabletPos = UBGeometryUtils::pointConstrainedInRect (event->hiResGlobalPos () - - mapToGlobal (QPoint (0, 0)), rect ()); - - UBStylusTool::Enum currentTool = (UBStylusTool::Enum)dc->stylusTool (); - - if (event->type () == QEvent::TabletPress || event->type () == QEvent::TabletEnterProximity) - { - if (event->pointerType () == QTabletEvent::Eraser) - { - dc->setStylusTool (UBStylusTool::Eraser); - mUsingTabletEraser = true; - } - else - { - if (mUsingTabletEraser && currentTool == UBStylusTool::Eraser) - { - dc->setStylusTool (dc->latestDrawingTool ()); - } - - mUsingTabletEraser = false; - } - } - - // if event are not Pen events, we drop the tablet stuff and route everything through mouse event - if (currentTool != UBStylusTool::Pen - && currentTool != UBStylusTool::Line - && currentTool != UBStylusTool::Marker - && !mMarkerPressureSensitive) - { - event->setAccepted (false); - return; - } - - QPointF scenePos = viewportTransform ().inverted ().map (tabletPos); - - qreal pressure = 1.0; - if (((currentTool == UBStylusTool::Pen || currentTool == UBStylusTool::Line) - && mPenPressureSensitive) - || (currentTool == UBStylusTool::Marker && mMarkerPressureSensitive)) - { - pressure = event->pressure (); - } - - bool acceptEvent = true; - - switch (event->type ()) - { - case QEvent::TabletPress: - { - mTabletStylusIsPressed = true; - - scene ()->inputDevicePress (scenePos, pressure); - - break; - } - case QEvent::TabletMove: - { - if (mTabletStylusIsPressed) - { - scene ()->inputDeviceMove (scenePos, pressure); - } - - acceptEvent = false; // rerouted to mouse move - - break; - - } - case QEvent::TabletRelease: - { - UBStylusTool::Enum currentTool = (UBStylusTool::Enum)dc->stylusTool (); - scene ()->setToolCursor (currentTool); - setToolCursor (currentTool); - - scene ()->inputDeviceRelease (); - - mPendingStylusReleaseEvent = false; - - mTabletStylusIsPressed = false; - mMouseButtonIsPressed = false; - - break; - } - default: - { - //NOOP - avoid compiler warning - } - } - - // ignore mouse press and mouse move tablet event so that it is rerouted to mouse events, - // documented in QTabletEvent Class Reference: - /* The event handler QWidget::tabletEvent() receives all three types of tablet events. - Qt will first send a tabletEvent then, if it is not accepted, it will send a mouse event. */ - // - // This is a workaround to the fact that tablet event are not delivered to child widget (like palettes) - // - - event->setAccepted (acceptEvent); - -} - -void -UBBoardView::mousePressEvent (QMouseEvent *event) -{ - if (isAbsurdPoint (event->pos ())) - { - event->accept (); - return; - } - - mMouseDownPos = event->pos (); - - if (event->button () == Qt::LeftButton && isInteractive ()) - { - UBStylusTool::Enum currentTool = (UBStylusTool::Enum)UBDrawingController::drawingController ()->stylusTool (); - - if (!mTabletStylusIsPressed) - mMouseButtonIsPressed = true; - - if (currentTool == UBStylusTool::ZoomIn) - { - mController->zoomIn (mapToScene (event->pos ())); - event->accept (); - } - else if (currentTool == UBStylusTool::ZoomOut) - { - mController->zoomOut (mapToScene (event->pos ())); - event->accept (); - } - else if (currentTool == UBStylusTool::Hand) - { - viewport ()->setCursor (QCursor (Qt::ClosedHandCursor)); - mPreviousPoint = event->posF (); - event->accept (); - } - else if (currentTool == UBStylusTool::Selector) - { - QGraphicsView::mousePressEvent (event); - } - else if (currentTool == UBStylusTool::Text) - { - int frameWidth = UBSettings::settings ()->objectFrameWidth; - QRectF fuzzyRect (0, 0, frameWidth * 4, frameWidth * 4); - fuzzyRect.moveCenter (mapToScene (mMouseDownPos)); - - UBGraphicsTextItem* foundTextItem = 0; - QListIterator it (scene ()->items (fuzzyRect)); - - while (it.hasNext () && !foundTextItem) - { - foundTextItem = qgraphicsitem_cast(it.next ()); - } - - if (foundTextItem) - { - mIsCreatingTextZone = false; - QGraphicsView::mousePressEvent (event); - } - else - { - scene ()->deselectAllItems (); - - if (!mRubberBand) - mRubberBand = new UBRubberBand (QRubberBand::Rectangle, this); - - mRubberBand->setGeometry (QRect (mMouseDownPos, QSize ())); - mRubberBand->show (); - mIsCreatingTextZone = true; - - event->accept (); - } - } - else if (currentTool == UBStylusTool::Capture) - { - scene ()->deselectAllItems (); - - if (!mRubberBand) - mRubberBand = new UBRubberBand (QRubberBand::Rectangle, this); - - mRubberBand->setGeometry (QRect (mMouseDownPos, QSize ())); - mRubberBand->show (); - mIsCreatingSceneGrabZone = true; - - event->accept (); - } - else - { - if(UBDrawingController::drawingController()->mActiveRuler==NULL) - { - viewport()->setCursor (QCursor (Qt::BlankCursor)); - } - - if (scene () && !mTabletStylusIsPressed) - { - scene ()->inputDevicePress (mapToScene (UBGeometryUtils::pointConstrainedInRect (event->pos (), rect ()))); - } - event->accept (); - } - } -} - -void -UBBoardView::mouseMoveEvent (QMouseEvent *event) -{ - UBStylusTool::Enum currentTool = (UBStylusTool::Enum)UBDrawingController::drawingController ()->stylusTool (); - - if (isAbsurdPoint (event->pos ())) - { - event->accept (); - return; - } - - if (currentTool == UBStylusTool::Hand && (mMouseButtonIsPressed || mTabletStylusIsPressed)) - { - QPointF eventPosition = event->posF (); - qreal dx = eventPosition.x () - mPreviousPoint.x (); - qreal dy = eventPosition.y () - mPreviousPoint.y (); - mController->handScroll (dx, dy); - mPreviousPoint = eventPosition; - event->accept (); - } - else if (currentTool == UBStylusTool::Selector) - { - QGraphicsView::mouseMoveEvent (event); - } - else if ((UBDrawingController::drawingController()->isDrawingTool()) - && !mMouseButtonIsPressed) - { - QGraphicsView::mouseMoveEvent (event); - } - else if (currentTool == UBStylusTool::Text || currentTool == UBStylusTool::Capture) - { - if (mRubberBand && (mIsCreatingTextZone || mIsCreatingSceneGrabZone)) - { - mRubberBand->setGeometry (QRect (mMouseDownPos, event->pos ()).normalized ()); - event->accept (); - } - else - { - QGraphicsView::mouseMoveEvent (event); - } - } - else - { - if (!mTabletStylusIsPressed && scene ()) - { - scene ()->inputDeviceMove (mapToScene (UBGeometryUtils::pointConstrainedInRect (event->pos (), rect ())), mMouseButtonIsPressed); - } - event->accept (); - } -} - -void -UBBoardView::mouseReleaseEvent (QMouseEvent *event) -{ - UBStylusTool::Enum currentTool = (UBStylusTool::Enum)UBDrawingController::drawingController ()->stylusTool (); - - scene ()->setToolCursor (currentTool); - setToolCursor (currentTool); - - // first propagate device release to the scene - if (scene ()) - scene ()->inputDeviceRelease (); - - if (currentTool == UBStylusTool::Selector) - { - QGraphicsView::mouseReleaseEvent (event); - } - else if (currentTool == UBStylusTool::Text) - { - if (mRubberBand) - mRubberBand->hide (); - - if (scene () && mRubberBand && mIsCreatingTextZone) - { - QRect rubberRect = mRubberBand->geometry (); - - UBGraphicsTextItem* textItem = scene ()->addText ("", mapToScene (rubberRect.topLeft ())); - event->accept (); - - UBDrawingController::drawingController ()->setStylusTool (UBStylusTool::Selector); - - textItem->setSelected (true); - } - else - { - QGraphicsView::mouseReleaseEvent (event); - } - - mIsCreatingTextZone = false; - } - else if (currentTool == UBStylusTool::Capture) - { - if (mRubberBand) - mRubberBand->hide (); - - if (scene () && mRubberBand && mIsCreatingSceneGrabZone && mRubberBand->geometry ().width () > 16) - { - QRect rect = mRubberBand->geometry (); - QPointF sceneTopLeft = mapToScene (rect.topLeft ()); - QPointF sceneBottomRight = mapToScene (rect.bottomRight ()); - QRectF sceneRect (sceneTopLeft, sceneBottomRight); - - mController->grabScene (sceneRect); - - event->accept (); - } - else - { - QGraphicsView::mouseReleaseEvent (event); - } - - mIsCreatingSceneGrabZone = false; - } - else - { - if (mPendingStylusReleaseEvent || mMouseButtonIsPressed) - { - event->accept (); - } - } - - mMouseButtonIsPressed = false; - mPendingStylusReleaseEvent = false; - mTabletStylusIsPressed = false; - -} - -void -UBBoardView::forcedTabletRelease () -{ - - if (mMouseButtonIsPressed || mTabletStylusIsPressed || mPendingStylusReleaseEvent) - { - qWarning () << "dirty mouse/tablet state:"; - qWarning () << "mMouseButtonIsPressed =" << mMouseButtonIsPressed; - qWarning () << "mTabletStylusIsPressed = " << mTabletStylusIsPressed; - qWarning () << "mPendingStylusReleaseEvent" << mPendingStylusReleaseEvent; - qWarning () << "forcing device release"; - - scene ()->inputDeviceRelease (); - - mMouseButtonIsPressed = false; - mTabletStylusIsPressed = false; - mPendingStylusReleaseEvent = false; - - } -} - -void -UBBoardView::mouseDoubleClickEvent (QMouseEvent *event) -{ - // We don't want a double click, we want two clicks - mousePressEvent (event); -} - -void -UBBoardView::wheelEvent (QWheelEvent *event) -{ - if (isInteractive () && event->orientation () == Qt::Vertical) - { - // Too many wheelEvent are sent, how should we handle them to "smoothly" zoom ? - // something like zoom( pow(zoomFactor, event->delta() / 120) ) - } - event->accept (); -} - -void -UBBoardView::leaveEvent (QEvent * event) -{ - if (scene ()) - scene ()->leaveEvent (event); - - QGraphicsView::leaveEvent (event); -} - -void -UBBoardView::drawItems (QPainter *painter, int numItems, - QGraphicsItem* items[], - const QStyleOptionGraphicsItem options[]) -{ - if (!mFilterZIndex) - { - QGraphicsView::drawItems (painter, numItems, items, options); - } - else - { - int count = 0; - - QGraphicsItem** itemsFiltered = new QGraphicsItem*[numItems]; - QStyleOptionGraphicsItem *optionsFiltered = new QStyleOptionGraphicsItem[numItems]; - - for (int i = 0; i < numItems; i++) - { - if (shouldDisplayItem (items[i])) - { - itemsFiltered[count] = items[i]; - optionsFiltered[count] = options[i]; - count++; - } - } - - QGraphicsView::drawItems (painter, count, itemsFiltered, optionsFiltered); - - delete[] optionsFiltered; - delete[] itemsFiltered; - } -} - -void -UBBoardView::dragEnterEvent (QDragEnterEvent *event) -{ - // TODO UB 4.x be smarter with drag accept code .... we cannot handle everything ... - event->acceptProposedAction (); -} - -void -UBBoardView::dragMoveEvent (QDragMoveEvent *event) -{ - event->acceptProposedAction (); -} - -void -UBBoardView::dropEvent (QDropEvent *event) -{ - if(!event->source() || dynamic_cast(event->source())) - { - mController->processMimeData (event->mimeData (), mapToScene (event->pos ())); - event->acceptProposedAction (); - } -} - -void -UBBoardView::resizeEvent (QResizeEvent * event) -{ - const qreal maxWidth = width () * 10; - const qreal maxHeight = height () * 10; - - setSceneRect (-(maxWidth / 2), -(maxHeight / 2), maxWidth, maxHeight); - centerOn (0, 0); - - emit resized (event); -} - -void -UBBoardView::drawBackground (QPainter *painter, const QRectF &rect) -{ - if (testAttribute (Qt::WA_TranslucentBackground)) - { - QGraphicsView::drawBackground (painter, rect); - return; - } - - bool darkBackground = scene () && scene ()->isDarkBackground (); - - if (darkBackground) - { - painter->fillRect (rect, QBrush (QColor (Qt::black))); - } - else - { - painter->fillRect (rect, QBrush (QColor (Qt::white))); - } - - if (transform ().m11 () > 0.5) - { - QColor bgCrossColor; - - if (darkBackground) - bgCrossColor = UBSettings::crossDarkBackground; - else - bgCrossColor = UBSettings::crossLightBackground; - - if (transform ().m11 () < 1.0) - { - int alpha = 255 * transform ().m11 () / 2; - bgCrossColor.setAlpha (alpha); // fade the crossing on small zooms - } - - painter->setPen (bgCrossColor); - - if (scene () && scene ()->isCrossedBackground ()) - { - qreal firstY = ((int) (rect.y () / UBSettings::crossSize)) * UBSettings::crossSize; - - for (qreal yPos = firstY; yPos < rect.y () + rect.height (); yPos += UBSettings::crossSize) - { - painter->drawLine (rect.x (), yPos, rect.x () + rect.width (), yPos); - } - - qreal firstX = ((int) (rect.x () / UBSettings::crossSize)) * UBSettings::crossSize; - - for (qreal xPos = firstX; xPos < rect.x () + rect.width (); xPos += UBSettings::crossSize) - { - painter->drawLine (xPos, rect.y (), xPos, rect.y () + rect.height ()); - } - } - } - - if (!mFilterZIndex && scene ()) - { - QSize pageNominalSize = scene ()->nominalSize (); - - if (pageNominalSize.isValid ()) - { - qreal penWidth = 8.0 / transform ().m11 (); - - QRectF pageRect (pageNominalSize.width () / -2, pageNominalSize.height () / -2 - , pageNominalSize.width (), pageNominalSize.height ()); - - pageRect.adjust (-penWidth / 2, -penWidth / 2, penWidth / 2, penWidth / 2); - - QColor docSizeColor; - - if (darkBackground) - docSizeColor = UBSettings::documentSizeMarkColorDarkBackground; - else - docSizeColor = UBSettings::documentSizeMarkColorLightBackground; - - QPen pen (docSizeColor); - pen.setWidth (penWidth); - painter->setPen (pen); - painter->drawRect (pageRect); - } - } -} - -void -UBBoardView::settingChanged (QVariant newValue) -{ - Q_UNUSED (newValue); - - mPenPressureSensitive = UBSettings::settings ()->boardPenPressureSensitive->get ().toBool (); - mMarkerPressureSensitive = UBSettings::settings ()->boardMarkerPressureSensitive->get ().toBool (); - mUseHighResTabletEvent = UBSettings::settings ()->boardUseHighResTabletEvent->get ().toBool (); -} - -void UBBoardView::virtualKeyboardActivated(bool b) -{ - UBPlatformUtils::setWindowNonActivableFlag(this, b); - mVirtualKeyboardActive = b; - setInteractive(!b); -} - - -// Apple remote desktop sends funny events when the transmission is bad - -bool -UBBoardView::isAbsurdPoint (QPoint point) -{ - QDesktopWidget *desktop = qApp->desktop (); - bool isValidPoint = false; - - for (int i = 0; i < desktop->numScreens (); i++) - { - QRect screenRect = desktop->screenGeometry (i); - isValidPoint = isValidPoint || screenRect.contains (point); - } - - return !isValidPoint; -} - -void -UBBoardView::focusOutEvent (QFocusEvent * event) -{ - Q_UNUSED (event); -} - -void -UBBoardView::setToolCursor (int tool) -{ - QWidget *controlViewport = viewport (); - switch (tool) - { - case UBStylusTool::Pen: - controlViewport->setCursor (UBResources::resources ()->penCursor); - break; - case UBStylusTool::Eraser: - controlViewport->setCursor (UBResources::resources ()->eraserCursor); - break; - case UBStylusTool::Marker: - controlViewport->setCursor (UBResources::resources ()->markerCursor); - break; - case UBStylusTool::Pointer: - controlViewport->setCursor (UBResources::resources ()->pointerCursor); - break; - case UBStylusTool::Hand: - controlViewport->setCursor (UBResources::resources ()->handCursor); - break; - case UBStylusTool::ZoomIn: - controlViewport->setCursor (UBResources::resources ()->zoomInCursor); - break; - case UBStylusTool::ZoomOut: - controlViewport->setCursor (UBResources::resources ()->zoomOutCursor); - break; - case UBStylusTool::Selector: - controlViewport->setCursor (UBResources::resources ()->arrowCursor); - break; - case UBStylusTool::Line: - controlViewport->setCursor (UBResources::resources ()->penCursor); - break; - case UBStylusTool::Text: - controlViewport->setCursor (UBResources::resources ()->textCursor); - break; - case UBStylusTool::Capture: - controlViewport->setCursor (UBResources::resources ()->penCursor); - break; - default: - Q_ASSERT (false); - //failsafe - controlViewport->setCursor (UBResources::resources ()->penCursor); - } -} - - + +#include "UBBoardView.h" + +#include + +#include "UBDrawingController.h" + +#include "frameworks/UBGeometryUtils.h" + +#include "core/UBSettings.h" +#include "core/UBMimeData.h" +#include "core/UBApplication.h" +#include "core/UBSetting.h" +#include "core/UBPersistenceManager.h" + +#include "network/UBHttpGet.h" + +#include "gui/UBStylusPalette.h" +#include "gui/UBRubberBand.h" +#include "gui/UBToolWidget.h" +#include "gui/UBResources.h" +#include "gui/UBMainWindow.h" + +#include "board/UBBoardController.h" + +#include "domain/UBGraphicsTextItem.h" +#include "domain/UBGraphicsPixmapItem.h" +#include "domain/UBGraphicsWidgetItem.h" +#include "domain/UBItem.h" + +#include "document/UBDocumentProxy.h" +#include "../gui/UBThumbnailWidget.h" + +#include "frameworks/UBPlatformUtils.h" + +#include "core/memcheck.h" + +UBBoardView::UBBoardView (UBBoardController* pController, QWidget* pParent) +: QGraphicsView (pParent) +, mController (pController) +, mIsCreatingTextZone (false) +, mIsCreatingSceneGrabZone (false) +{ + init (); + + mFilterZIndex = false; +} + +UBBoardView::UBBoardView (UBBoardController* pController, int pStartLayer, int pEndLayer, QWidget* pParent) +: QGraphicsView (pParent) +, mController (pController) +{ + init (); + + mStartLayer = pStartLayer; + mEndLayer = pEndLayer; + + mFilterZIndex = true; +} + +UBBoardView::~UBBoardView () { + //NOOP +} + +void +UBBoardView::init () +{ + connect (UBSettings::settings ()->boardPenPressureSensitive, SIGNAL (changed (QVariant)), + this, SLOT (settingChanged (QVariant))); + + connect (UBSettings::settings ()->boardMarkerPressureSensitive, SIGNAL (changed (QVariant)), + this, SLOT (settingChanged (QVariant))); + + connect (UBSettings::settings ()->boardUseHighResTabletEvent, SIGNAL (changed (QVariant)), + this, SLOT (settingChanged (QVariant))); + + setWindowFlags (Qt::FramelessWindowHint); + setFrameStyle (QFrame::NoFrame); + setRenderHints (QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing); + setVerticalScrollBarPolicy (Qt::ScrollBarAlwaysOff); + setHorizontalScrollBarPolicy (Qt::ScrollBarAlwaysOff); + setAcceptDrops (true); + + setOptimizationFlag (QGraphicsView::IndirectPainting); // enable UBBoardView::drawItems filter + + mTabletStylusIsPressed = false; + mMouseButtonIsPressed = false; + mPendingStylusReleaseEvent = false; + + setCacheMode (QGraphicsView::CacheBackground); + + mUsingTabletEraser = false; + mIsCreatingTextZone = false; + mRubberBand = 0; + + mVirtualKeyboardActive = false; + + settingChanged (QVariant ()); + + unsetCursor(); +} + +UBGraphicsScene* +UBBoardView::scene () +{ + return qobject_cast (QGraphicsView::scene ()); +} + +void +UBBoardView::hideEvent (QHideEvent * event) +{ + Q_UNUSED (event); + emit hidden (); +} + +void +UBBoardView::showEvent (QShowEvent * event) +{ + Q_UNUSED (event); + emit shown (); +} + +void +UBBoardView::keyPressEvent (QKeyEvent *event) +{ + // send to the scene anyway + QApplication::sendEvent (scene (), event); + + if (!event->isAccepted ()) + { + switch (event->key ()) + { + case Qt::Key_Up: + case Qt::Key_PageUp: + case Qt::Key_Left: + { + mController->previousScene (); + break; + } + + case Qt::Key_Down: + case Qt::Key_PageDown: + case Qt::Key_Right: + case Qt::Key_Space: + { + mController->nextScene (); + break; + } + + case Qt::Key_Home: + { + mController->firstScene (); + break; + } + case Qt::Key_End: + { + mController->lastScene (); + break; + } + case Qt::Key_Insert: + { + mController->addScene (); + break; + } + } + + + if (event->modifiers () & Qt::ControlModifier) // keep only ctrl/cmd keys + { + switch (event->key ()) + { + case Qt::Key_Plus: + case Qt::Key_I: + { + mController->zoomIn (); + event->accept (); + break; + } + case Qt::Key_Minus: + case Qt::Key_O: + { + mController->zoomOut (); + event->accept (); + break; + } + case Qt::Key_0: + { + mController->zoomRestore (); + event->accept (); + break; + } + case Qt::Key_Left: + { + mController->handScroll (-100, 0); + event->accept (); + break; + } + case Qt::Key_Right: + { + mController->handScroll (100, 0); + event->accept (); + break; + } + case Qt::Key_Up: + { + mController->handScroll (0, -100); + event->accept (); + break; + } + case Qt::Key_Down: + { + mController->handScroll (0, 100); + event->accept (); + break; + } + default: + { + // NOOP + } + } + } + } +} + +bool +UBBoardView::event (QEvent * e) +{ + if (e->type () == QEvent::Gesture) + { + QGestureEvent *gestureEvent = dynamic_cast (e); + if (gestureEvent) + { + QSwipeGesture* swipe = dynamic_cast (gestureEvent->gesture (Qt::SwipeGesture)); + + if (swipe) + { + if (swipe->horizontalDirection () == QSwipeGesture::Left) + { + mController->previousScene (); + gestureEvent->setAccepted (swipe, true); + } + + if (swipe->horizontalDirection () == QSwipeGesture::Right) + { + mController->nextScene (); + gestureEvent->setAccepted (swipe, true); + } + } + } + } + + return QGraphicsView::event (e); +} + +void +UBBoardView::tabletEvent (QTabletEvent * event) +{ + if (!mUseHighResTabletEvent) + { + event->setAccepted (false); + return; + } + + UBDrawingController *dc = UBDrawingController::drawingController (); + + QPointF tabletPos = UBGeometryUtils::pointConstrainedInRect (event->hiResGlobalPos () + - mapToGlobal (QPoint (0, 0)), rect ()); + + UBStylusTool::Enum currentTool = (UBStylusTool::Enum)dc->stylusTool (); + + if (event->type () == QEvent::TabletPress || event->type () == QEvent::TabletEnterProximity) + { + if (event->pointerType () == QTabletEvent::Eraser) + { + dc->setStylusTool (UBStylusTool::Eraser); + mUsingTabletEraser = true; + } + else + { + if (mUsingTabletEraser && currentTool == UBStylusTool::Eraser) + { + dc->setStylusTool (dc->latestDrawingTool ()); + } + + mUsingTabletEraser = false; + } + } + + // if event are not Pen events, we drop the tablet stuff and route everything through mouse event + if (currentTool != UBStylusTool::Pen + && currentTool != UBStylusTool::Line + && currentTool != UBStylusTool::Marker + && !mMarkerPressureSensitive) + { + event->setAccepted (false); + return; + } + + QPointF scenePos = viewportTransform ().inverted ().map (tabletPos); + + qreal pressure = 1.0; + if (((currentTool == UBStylusTool::Pen || currentTool == UBStylusTool::Line) + && mPenPressureSensitive) + || (currentTool == UBStylusTool::Marker && mMarkerPressureSensitive)) + { + pressure = event->pressure (); + } + + bool acceptEvent = true; + + switch (event->type ()) + { + case QEvent::TabletPress: + { + mTabletStylusIsPressed = true; + + scene ()->inputDevicePress (scenePos, pressure); + + break; + } + case QEvent::TabletMove: + { + if (mTabletStylusIsPressed) + { + scene ()->inputDeviceMove (scenePos, pressure); + } + + acceptEvent = false; // rerouted to mouse move + + break; + + } + case QEvent::TabletRelease: + { + UBStylusTool::Enum currentTool = (UBStylusTool::Enum)dc->stylusTool (); + scene ()->setToolCursor (currentTool); + setToolCursor (currentTool); + + scene ()->inputDeviceRelease (); + + mPendingStylusReleaseEvent = false; + + mTabletStylusIsPressed = false; + mMouseButtonIsPressed = false; + + break; + } + default: + { + //NOOP - avoid compiler warning + } + } + + // ignore mouse press and mouse move tablet event so that it is rerouted to mouse events, + // documented in QTabletEvent Class Reference: + /* The event handler QWidget::tabletEvent() receives all three types of tablet events. + Qt will first send a tabletEvent then, if it is not accepted, it will send a mouse event. */ + // + // This is a workaround to the fact that tablet event are not delivered to child widget (like palettes) + // + + event->setAccepted (acceptEvent); + +} + +void +UBBoardView::mousePressEvent (QMouseEvent *event) +{ + if (isAbsurdPoint (event->pos ())) + { + event->accept (); + return; + } + + mMouseDownPos = event->pos (); + + if (event->button () == Qt::LeftButton && isInteractive ()) + { + UBStylusTool::Enum currentTool = (UBStylusTool::Enum)UBDrawingController::drawingController ()->stylusTool (); + + if (!mTabletStylusIsPressed) + mMouseButtonIsPressed = true; + + if (currentTool == UBStylusTool::ZoomIn) + { + mController->zoomIn (mapToScene (event->pos ())); + event->accept (); + } + else if (currentTool == UBStylusTool::ZoomOut) + { + mController->zoomOut (mapToScene (event->pos ())); + event->accept (); + } + else if (currentTool == UBStylusTool::Hand) + { + viewport ()->setCursor (QCursor (Qt::ClosedHandCursor)); + mPreviousPoint = event->posF (); + event->accept (); + } + else if (currentTool == UBStylusTool::Selector) + { + QGraphicsView::mousePressEvent (event); + } + else if (currentTool == UBStylusTool::Text) + { + int frameWidth = UBSettings::settings ()->objectFrameWidth; + QRectF fuzzyRect (0, 0, frameWidth * 4, frameWidth * 4); + fuzzyRect.moveCenter (mapToScene (mMouseDownPos)); + + UBGraphicsTextItem* foundTextItem = 0; + QListIterator it (scene ()->items (fuzzyRect)); + + while (it.hasNext () && !foundTextItem) + { + foundTextItem = qgraphicsitem_cast(it.next ()); + } + + if (foundTextItem) + { + mIsCreatingTextZone = false; + QGraphicsView::mousePressEvent (event); + } + else + { + scene ()->deselectAllItems (); + + if (!mRubberBand) + mRubberBand = new UBRubberBand (QRubberBand::Rectangle, this); + + mRubberBand->setGeometry (QRect (mMouseDownPos, QSize ())); + mRubberBand->show (); + mIsCreatingTextZone = true; + + event->accept (); + } + } + else if (currentTool == UBStylusTool::Capture) + { + scene ()->deselectAllItems (); + + if (!mRubberBand) + mRubberBand = new UBRubberBand (QRubberBand::Rectangle, this); + + mRubberBand->setGeometry (QRect (mMouseDownPos, QSize ())); + mRubberBand->show (); + mIsCreatingSceneGrabZone = true; + + event->accept (); + } + else + { + if(UBDrawingController::drawingController()->mActiveRuler==NULL) + { + viewport()->setCursor (QCursor (Qt::BlankCursor)); + } + + if (scene () && !mTabletStylusIsPressed) + { + scene ()->inputDevicePress (mapToScene (UBGeometryUtils::pointConstrainedInRect (event->pos (), rect ()))); + } + event->accept (); + } + } +} + +void +UBBoardView::mouseMoveEvent (QMouseEvent *event) +{ + UBStylusTool::Enum currentTool = (UBStylusTool::Enum)UBDrawingController::drawingController ()->stylusTool (); + + if (isAbsurdPoint (event->pos ())) + { + event->accept (); + return; + } + + if (currentTool == UBStylusTool::Hand && (mMouseButtonIsPressed || mTabletStylusIsPressed)) + { + QPointF eventPosition = event->posF (); + qreal dx = eventPosition.x () - mPreviousPoint.x (); + qreal dy = eventPosition.y () - mPreviousPoint.y (); + mController->handScroll (dx, dy); + mPreviousPoint = eventPosition; + event->accept (); + } + else if (currentTool == UBStylusTool::Selector) + { + QGraphicsView::mouseMoveEvent (event); + } + else if ((UBDrawingController::drawingController()->isDrawingTool()) + && !mMouseButtonIsPressed) + { + QGraphicsView::mouseMoveEvent (event); + } + else if (currentTool == UBStylusTool::Text || currentTool == UBStylusTool::Capture) + { + if (mRubberBand && (mIsCreatingTextZone || mIsCreatingSceneGrabZone)) + { + mRubberBand->setGeometry (QRect (mMouseDownPos, event->pos ()).normalized ()); + event->accept (); + } + else + { + QGraphicsView::mouseMoveEvent (event); + } + } + else + { + if (!mTabletStylusIsPressed && scene ()) + { + scene ()->inputDeviceMove (mapToScene (UBGeometryUtils::pointConstrainedInRect (event->pos (), rect ())), mMouseButtonIsPressed); + } + event->accept (); + } +} + +void +UBBoardView::mouseReleaseEvent (QMouseEvent *event) +{ + UBStylusTool::Enum currentTool = (UBStylusTool::Enum)UBDrawingController::drawingController ()->stylusTool (); + + scene ()->setToolCursor (currentTool); + setToolCursor (currentTool); + + // first propagate device release to the scene + if (scene ()) + scene ()->inputDeviceRelease (); + + if (currentTool == UBStylusTool::Selector) + { + QGraphicsView::mouseReleaseEvent (event); + } + else if (currentTool == UBStylusTool::Text) + { + if (mRubberBand) + mRubberBand->hide (); + + if (scene () && mRubberBand && mIsCreatingTextZone) + { + QRect rubberRect = mRubberBand->geometry (); + + UBGraphicsTextItem* textItem = scene ()->addText ("", mapToScene (rubberRect.topLeft ())); + event->accept (); + + UBDrawingController::drawingController ()->setStylusTool (UBStylusTool::Selector); + + textItem->setSelected (true); + } + else + { + QGraphicsView::mouseReleaseEvent (event); + } + + mIsCreatingTextZone = false; + } + else if (currentTool == UBStylusTool::Capture) + { + if (mRubberBand) + mRubberBand->hide (); + + if (scene () && mRubberBand && mIsCreatingSceneGrabZone && mRubberBand->geometry ().width () > 16) + { + QRect rect = mRubberBand->geometry (); + QPointF sceneTopLeft = mapToScene (rect.topLeft ()); + QPointF sceneBottomRight = mapToScene (rect.bottomRight ()); + QRectF sceneRect (sceneTopLeft, sceneBottomRight); + + mController->grabScene (sceneRect); + + event->accept (); + } + else + { + QGraphicsView::mouseReleaseEvent (event); + } + + mIsCreatingSceneGrabZone = false; + } + else + { + if (mPendingStylusReleaseEvent || mMouseButtonIsPressed) + { + event->accept (); + } + } + + mMouseButtonIsPressed = false; + mPendingStylusReleaseEvent = false; + mTabletStylusIsPressed = false; + +} + +void +UBBoardView::forcedTabletRelease () +{ + + if (mMouseButtonIsPressed || mTabletStylusIsPressed || mPendingStylusReleaseEvent) + { + qWarning () << "dirty mouse/tablet state:"; + qWarning () << "mMouseButtonIsPressed =" << mMouseButtonIsPressed; + qWarning () << "mTabletStylusIsPressed = " << mTabletStylusIsPressed; + qWarning () << "mPendingStylusReleaseEvent" << mPendingStylusReleaseEvent; + qWarning () << "forcing device release"; + + scene ()->inputDeviceRelease (); + + mMouseButtonIsPressed = false; + mTabletStylusIsPressed = false; + mPendingStylusReleaseEvent = false; + + } +} + +void +UBBoardView::mouseDoubleClickEvent (QMouseEvent *event) +{ + // We don't want a double click, we want two clicks + mousePressEvent (event); +} + +void +UBBoardView::wheelEvent (QWheelEvent *event) +{ + if (isInteractive () && event->orientation () == Qt::Vertical) + { + // Too many wheelEvent are sent, how should we handle them to "smoothly" zoom ? + // something like zoom( pow(zoomFactor, event->delta() / 120) ) + } + event->accept (); +} + +void +UBBoardView::leaveEvent (QEvent * event) +{ + if (scene ()) + scene ()->leaveEvent (event); + + QGraphicsView::leaveEvent (event); +} + +void +UBBoardView::drawItems (QPainter *painter, int numItems, + QGraphicsItem* items[], + const QStyleOptionGraphicsItem options[]) +{ + if (!mFilterZIndex) + { + QGraphicsView::drawItems (painter, numItems, items, options); + } + else + { + int count = 0; + + QGraphicsItem** itemsFiltered = new QGraphicsItem*[numItems]; + QStyleOptionGraphicsItem *optionsFiltered = new QStyleOptionGraphicsItem[numItems]; + + for (int i = 0; i < numItems; i++) + { + if (shouldDisplayItem (items[i])) + { + itemsFiltered[count] = items[i]; + optionsFiltered[count] = options[i]; + count++; + } + } + + QGraphicsView::drawItems (painter, count, itemsFiltered, optionsFiltered); + + delete[] optionsFiltered; + delete[] itemsFiltered; + } +} + +void +UBBoardView::dragEnterEvent (QDragEnterEvent *event) +{ + // TODO UB 4.x be smarter with drag accept code .... we cannot handle everything ... + event->acceptProposedAction (); +} + +void +UBBoardView::dragMoveEvent (QDragMoveEvent *event) +{ + event->acceptProposedAction (); +} + +void +UBBoardView::dropEvent (QDropEvent *event) +{ + if(!event->source() || dynamic_cast(event->source())) + { + mController->processMimeData (event->mimeData (), mapToScene (event->pos ())); + event->acceptProposedAction (); + } +} + +void +UBBoardView::resizeEvent (QResizeEvent * event) +{ + const qreal maxWidth = width () * 10; + const qreal maxHeight = height () * 10; + + setSceneRect (-(maxWidth / 2), -(maxHeight / 2), maxWidth, maxHeight); + centerOn (0, 0); + + emit resized (event); +} + +void +UBBoardView::drawBackground (QPainter *painter, const QRectF &rect) +{ + if (testAttribute (Qt::WA_TranslucentBackground)) + { + QGraphicsView::drawBackground (painter, rect); + return; + } + + bool darkBackground = scene () && scene ()->isDarkBackground (); + + if (darkBackground) + { + painter->fillRect (rect, QBrush (QColor (Qt::black))); + } + else + { + painter->fillRect (rect, QBrush (QColor (Qt::white))); + } + + if (transform ().m11 () > 0.5) + { + QColor bgCrossColor; + + if (darkBackground) + bgCrossColor = UBSettings::crossDarkBackground; + else + bgCrossColor = UBSettings::crossLightBackground; + + if (transform ().m11 () < 1.0) + { + int alpha = 255 * transform ().m11 () / 2; + bgCrossColor.setAlpha (alpha); // fade the crossing on small zooms + } + + painter->setPen (bgCrossColor); + + if (scene () && scene ()->isCrossedBackground ()) + { + qreal firstY = ((int) (rect.y () / UBSettings::crossSize)) * UBSettings::crossSize; + + for (qreal yPos = firstY; yPos < rect.y () + rect.height (); yPos += UBSettings::crossSize) + { + painter->drawLine (rect.x (), yPos, rect.x () + rect.width (), yPos); + } + + qreal firstX = ((int) (rect.x () / UBSettings::crossSize)) * UBSettings::crossSize; + + for (qreal xPos = firstX; xPos < rect.x () + rect.width (); xPos += UBSettings::crossSize) + { + painter->drawLine (xPos, rect.y (), xPos, rect.y () + rect.height ()); + } + } + } + + if (!mFilterZIndex && scene ()) + { + QSize pageNominalSize = scene ()->nominalSize (); + + if (pageNominalSize.isValid ()) + { + qreal penWidth = 8.0 / transform ().m11 (); + + QRectF pageRect (pageNominalSize.width () / -2, pageNominalSize.height () / -2 + , pageNominalSize.width (), pageNominalSize.height ()); + + pageRect.adjust (-penWidth / 2, -penWidth / 2, penWidth / 2, penWidth / 2); + + QColor docSizeColor; + + if (darkBackground) + docSizeColor = UBSettings::documentSizeMarkColorDarkBackground; + else + docSizeColor = UBSettings::documentSizeMarkColorLightBackground; + + QPen pen (docSizeColor); + pen.setWidth (penWidth); + painter->setPen (pen); + painter->drawRect (pageRect); + } + } +} + +void +UBBoardView::settingChanged (QVariant newValue) +{ + Q_UNUSED (newValue); + + mPenPressureSensitive = UBSettings::settings ()->boardPenPressureSensitive->get ().toBool (); + mMarkerPressureSensitive = UBSettings::settings ()->boardMarkerPressureSensitive->get ().toBool (); + mUseHighResTabletEvent = UBSettings::settings ()->boardUseHighResTabletEvent->get ().toBool (); +} + +void UBBoardView::virtualKeyboardActivated(bool b) +{ + UBPlatformUtils::setWindowNonActivableFlag(this, b); + mVirtualKeyboardActive = b; + setInteractive(!b); +} + + +// Apple remote desktop sends funny events when the transmission is bad + +bool +UBBoardView::isAbsurdPoint (QPoint point) +{ + QDesktopWidget *desktop = qApp->desktop (); + bool isValidPoint = false; + + for (int i = 0; i < desktop->numScreens (); i++) + { + QRect screenRect = desktop->screenGeometry (i); + isValidPoint = isValidPoint || screenRect.contains (point); + } + + return !isValidPoint; +} + +void +UBBoardView::focusOutEvent (QFocusEvent * event) +{ + Q_UNUSED (event); +} + +void +UBBoardView::setToolCursor (int tool) +{ + QWidget *controlViewport = viewport (); + switch (tool) + { + case UBStylusTool::Pen: + controlViewport->setCursor (UBResources::resources ()->penCursor); + break; + case UBStylusTool::Eraser: + controlViewport->setCursor (UBResources::resources ()->eraserCursor); + break; + case UBStylusTool::Marker: + controlViewport->setCursor (UBResources::resources ()->markerCursor); + break; + case UBStylusTool::Pointer: + controlViewport->setCursor (UBResources::resources ()->pointerCursor); + break; + case UBStylusTool::Hand: + controlViewport->setCursor (UBResources::resources ()->handCursor); + break; + case UBStylusTool::ZoomIn: + controlViewport->setCursor (UBResources::resources ()->zoomInCursor); + break; + case UBStylusTool::ZoomOut: + controlViewport->setCursor (UBResources::resources ()->zoomOutCursor); + break; + case UBStylusTool::Selector: + controlViewport->setCursor (UBResources::resources ()->arrowCursor); + break; + case UBStylusTool::Line: + controlViewport->setCursor (UBResources::resources ()->penCursor); + break; + case UBStylusTool::Text: + controlViewport->setCursor (UBResources::resources ()->textCursor); + break; + case UBStylusTool::Capture: + controlViewport->setCursor (UBResources::resources ()->penCursor); + break; + default: + Q_ASSERT (false); + //failsafe + controlViewport->setCursor (UBResources::resources ()->penCursor); + } +} + + diff --git a/src/core/UBPreferencesController.cpp b/src/core/UBPreferencesController.cpp index ff357ee9..37a3bc37 100644 --- a/src/core/UBPreferencesController.cpp +++ b/src/core/UBPreferencesController.cpp @@ -451,6 +451,7 @@ void UBPreferencesController::toolbarPositionChanged(bool checked) UBSettings* settings = UBSettings::settings(); settings->appToolBarPositionedAtTop->set(mPreferencesUI->toolbarAtTopRadioButton->isChecked()); + } void UBPreferencesController::toolbarOrientationVertical(bool checked) diff --git a/src/desktop/UBDesktopAnnotationController.cpp b/src/desktop/UBDesktopAnnotationController.cpp index d7a4a9cd..f6073a13 100644 --- a/src/desktop/UBDesktopAnnotationController.cpp +++ b/src/desktop/UBDesktopAnnotationController.cpp @@ -1,8 +1,16 @@ /* - * UNWindowController.cpp + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * Created on: Jan 15, 2009 - * Author: julienbachmann + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ #include @@ -90,6 +98,7 @@ UBDesktopAnnotationController::UBDesktopAnnotationController(QObject *parent) mKeyboardPalette = UBKeyboardPalette::create(mTransparentDrawingView); mKeyboardPalette->setParent(mTransparentDrawingView); connect(mKeyboardPalette, SIGNAL(keyboardActivated(bool)), mTransparentDrawingView, SLOT(virtualKeyboardActivated(bool))); + connect(mKeyboardPalette, SIGNAL(moved(QPoint)), this, SLOT(refreshMask())); } connect(mDesktopPalette, SIGNAL(uniboardClick()), this, SLOT(goToUniboard())); @@ -143,12 +152,16 @@ UBDesktopAnnotationController::UBDesktopAnnotationController(QObject *parent) connect(&mHoldTimerMarker, SIGNAL(timeout()), this, SLOT(markerActionReleased())); connect(&mHoldTimerEraser, SIGNAL(timeout()), this, SLOT(eraserActionReleased())); + connect(mDesktopPalette, SIGNAL(moving()), this, SLOT(refreshMask())); + connect(mLibPalette, SIGNAL(resized()), this, SLOT(refreshMask())); + onDesktopPaletteMaximized(); } void UBDesktopAnnotationController::showKeyboard(bool show) { mKeyboardPalette->setVisible(show); + updateMask(true); // mDesktopPalette->showVirtualKeyboard(show); } @@ -332,6 +345,10 @@ void UBDesktopAnnotationController::showWindow() UBPlatformUtils::setDesktopMode(true); mDesktopPalette->appear(); + +#ifdef Q_WS_X11 + updateMask(true); +#endif } @@ -343,7 +360,15 @@ void UBDesktopAnnotationController::close() void UBDesktopAnnotationController::stylusToolChanged(int tool) { - Q_UNUSED(tool); + UBStylusTool::Enum eTool = (UBStylusTool::Enum)tool; + mDesktopPalette->notifySelectorSelection(UBStylusTool::Selector == eTool); + + if(UBStylusTool::Selector != eTool) + { + UBApplication::mainWindow->actionVirtualKeyboard->setChecked(false); + mKeyboardPalette->setVisible(false); + } + updateBackground(); } @@ -356,6 +381,9 @@ void UBDesktopAnnotationController::updateBackground() || UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Selector) { newBrush = QBrush(Qt::transparent); +#ifdef Q_WS_X11 + updateMask(true); +#endif } else { @@ -363,6 +391,9 @@ void UBDesktopAnnotationController::updateBackground() newBrush = QBrush(QColor(127, 127, 127, 15)); #else newBrush = QBrush(QColor(127, 127, 127, 1)); +#endif +#ifdef Q_WS_X11 + updateMask(false); #endif } @@ -389,6 +420,8 @@ void UBDesktopAnnotationController::goToUniboard() UBPlatformUtils::setDesktopMode(false); + UBApplication::mainWindow->actionVirtualKeyboard->setEnabled(true); + emit restoreUniboard(); } @@ -751,3 +784,83 @@ void UBDesktopAnnotationController::onTransparentWidgetResized() // qDebug() << "mLibPalette (" << mLibPalette->width() << "," << mLibPalette->height() << ")"; mLibPalette->resize(mLibPalette->width(), mTransparentDrawingView->height()); } + +void UBDesktopAnnotationController::updateMask(bool bTransparent) +{ + if(bTransparent) + { + // Here we have to generate a new mask. This method is certainly resource + // consuming but for the moment this is the only solution that I found. + mMask = QPixmap(mTransparentDrawingView->width(), mTransparentDrawingView->height()); + + QPainter p; + + p.begin(&mMask); + + p.setPen(Qt::red); + p.setBrush(QBrush(Qt::red)); + + // Here we draw the widget mask + if(mDesktopPalette->isVisible()) + { + p.drawRect(mDesktopPalette->geometry().x(), mDesktopPalette->geometry().y(), mDesktopPalette->width(), mDesktopPalette->height()); + } + if(mKeyboardPalette->isVisible()) + { + p.drawRect(mKeyboardPalette->geometry().x(), mKeyboardPalette->geometry().y(), mKeyboardPalette->width(), mKeyboardPalette->height()); + } + if(mLibPalette->isVisible()) + { + p.drawRect(mLibPalette->geometry().x(), mLibPalette->geometry().y(), mLibPalette->width(), mLibPalette->height()); + } + + p.end(); + + // Then we add the annotations. We create another painter because we need to + // apply transformations on it for coordinates matching + QPainter annotationPainter; + + QTransform trans; + trans.translate(mTransparentDrawingView->width()/2, mTransparentDrawingView->height()/2); + + annotationPainter.begin(&mMask); + annotationPainter.setPen(Qt::red); + annotationPainter.setBrush(Qt::red); + + annotationPainter.setTransform(trans); + + QList allItems = mTransparentDrawingScene->items(); + + for(int i = 0; i < allItems.size(); i++) + { + QGraphicsItem* pCrntItem = allItems.at(i); + + if(pCrntItem->isVisible()) + { + QPainterPath crntPath = pCrntItem->shape(); + QRectF rect = crntPath.boundingRect(); + + annotationPainter.drawRect(rect); + } + } + + annotationPainter.end(); + + mTransparentDrawingView->setMask(mMask.createMaskFromColor(Qt::black)); + } + else + { + // Remove the mask + QPixmap noMask(mTransparentDrawingView->width(), mTransparentDrawingView->height()); + mTransparentDrawingView->setMask(noMask.mask()); + } +} + +void UBDesktopAnnotationController::refreshMask() +{ + if(mIsFullyTransparent + || UBDrawingController::drawingController()->stylusTool() == UBStylusTool::Selector) + { + updateMask(true); + } +} diff --git a/src/desktop/UBDesktopAnnotationController.h b/src/desktop/UBDesktopAnnotationController.h index d595c04a..605ce5d9 100644 --- a/src/desktop/UBDesktopAnnotationController.h +++ b/src/desktop/UBDesktopAnnotationController.h @@ -1,8 +1,16 @@ /* - * UNWindowController.h + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * Created on: Jan 15, 2009 - * Author: julienbachmann + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ #ifndef UBUNINOTESWINDOWCONTROLLER_H_ @@ -94,10 +102,12 @@ class UBDesktopAnnotationController : public QObject void onDesktopPaletteMaximized(); void onDesktopPaletteMinimize(); void onTransparentWidgetResized(); + void refreshMask(); private: void setAssociatedPalettePosition(UBActionPalette* palette, const QString& actionName); void togglePropertyPalette(UBActionPalette* palette); + void updateMask(bool bTransparent); UBDesktopPalette *mDesktopPalette; UBKeyboardPalette *mKeyboardPalette; @@ -126,6 +136,8 @@ class UBDesktopAnnotationController : public QObject int mBoardStylusTool; int mDesktopStylusTool; + QPixmap mMask; + }; #endif /* UBUNINOTESWINDOWCONTROLLER_H_ */ diff --git a/src/desktop/UBDesktopPalette.cpp b/src/desktop/UBDesktopPalette.cpp index 6ec00c8a..f881f58a 100644 --- a/src/desktop/UBDesktopPalette.cpp +++ b/src/desktop/UBDesktopPalette.cpp @@ -36,9 +36,7 @@ UBDesktopPalette::UBDesktopPalette(QWidget *parent) actions << UBApplication::mainWindow->actionPen; actions << UBApplication::mainWindow->actionEraser; actions << UBApplication::mainWindow->actionMarker; -#ifndef Q_WS_X11 actions << UBApplication::mainWindow->actionSelector; -#endif actions << UBApplication::mainWindow->actionPointer; if (UBPlatformUtils::hasVirtualKeyboard()) @@ -152,9 +150,7 @@ void UBDesktopPalette::maximizeMe() actions << UBApplication::mainWindow->actionPen; actions << UBApplication::mainWindow->actionEraser; actions << UBApplication::mainWindow->actionMarker; -#ifndef Q_WS_X11 actions << UBApplication::mainWindow->actionSelector; -#endif actions << UBApplication::mainWindow->actionPointer; if (UBPlatformUtils::hasVirtualKeyboard()) actions << UBApplication::mainWindow->actionVirtualKeyboard; @@ -221,3 +217,8 @@ QPoint UBDesktopPalette::buttonPos(QAction *action) return p; } + +void UBDesktopPalette::notifySelectorSelection(bool selected) +{ + UBApplication::mainWindow->actionVirtualKeyboard->setEnabled(selected); +} diff --git a/src/desktop/UBDesktopPalette.h b/src/desktop/UBDesktopPalette.h index 83c01eab..17168b85 100644 --- a/src/desktop/UBDesktopPalette.h +++ b/src/desktop/UBDesktopPalette.h @@ -27,6 +27,7 @@ class UBDesktopPalette : public UBActionPalette void disappearForCapture(); void appear(); QPoint buttonPos(QAction* action); + void notifySelectorSelection(bool selected); signals: void uniboardClick(); diff --git a/src/domain/UBAbstractWidget.cpp b/src/domain/UBAbstractWidget.cpp index 6ff6116b..a5fafc18 100644 --- a/src/domain/UBAbstractWidget.cpp +++ b/src/domain/UBAbstractWidget.cpp @@ -44,8 +44,8 @@ UBAbstractWidget::UBAbstractWidget(const QUrl& pWidgetUrl, QWidget *parent) , mInitialLoadDone(false) , mLoadIsErronous(false) , mIsFreezable(true) - , mCanBeContent(true) - , mCanBeTool(true) + , mCanBeContent(0) + , mCanBeTool(0) , mIsFrozen(false) , mIsTakingSnapshot(false) { @@ -74,12 +74,51 @@ UBAbstractWidget::UBAbstractWidget(const QUrl& pWidgetUrl, QWidget *parent) setMouseTracking(true); } +bool UBAbstractWidget::canBeContent() +{ + // if we under MAC OS + #if defined(Q_OS_MAC) + return mCanBeContent & OSType::type_MAC; + #endif + + // if we under UNIX OS + #if defined(Q_OS_UNIX) + return mCanBeContent & OSType::type_UNIX; + #endif + + // if we under WINDOWS OS + #if defined(Q_OS_WIN) + return mCanBeContent & OSType::type_WIN; + #endif +} + +bool UBAbstractWidget::canBeTool() +{ + // if we under MAC OS + #if defined(Q_OS_MAC) + return mCanBeTool & OSType::type_MAC; + #endif + + // if we under UNIX OS + #if defined(Q_OS_UNIX) + return mCanBeTool & OSType::type_UNIX; + #endif + + // if we under WINDOWS OS + #if defined(Q_OS_WIN) + return mCanBeTool & OSType::type_WIN; + #endif +} UBAbstractWidget::~UBAbstractWidget() { // NOOP } +void UBAbstractWidget::loadMainHtml() +{ + QWebView::load(mMainHtmlUrl); +} bool UBAbstractWidget::event(QEvent *event) { diff --git a/src/domain/UBAbstractWidget.h b/src/domain/UBAbstractWidget.h index e96706e9..5c077d04 100644 --- a/src/domain/UBAbstractWidget.h +++ b/src/domain/UBAbstractWidget.h @@ -39,6 +39,8 @@ class UBAbstractWidget : public UBRoutedMouseEventWebView UBAbstractWidget(const QUrl& pWidgetUrl, QWidget *parent = 0); virtual ~UBAbstractWidget(); + void loadMainHtml(); + QUrl mainHtml() { return mMainHtmlUrl; @@ -64,15 +66,8 @@ class UBAbstractWidget : public UBRoutedMouseEventWebView return mNominalSize; } - bool canBeContent() const - { - return mCanBeContent; - } - - bool canBeTool() const - { - return mCanBeTool; - } + bool canBeContent(); + bool canBeTool(); bool hasLoadedSuccessfully() const { @@ -123,8 +118,16 @@ class UBAbstractWidget : public UBRoutedMouseEventWebView bool mLoadIsErronous; bool mIsFreezable; - bool mCanBeContent; - bool mCanBeTool; + int mCanBeContent; + int mCanBeTool; + enum OSType + { + type_NONE = 0, // 0000 + type_WIN = 1, // 0001 + type_MAC = 2, // 0010 + type_UNIX = 4, // 0100 + type_ALL = 7, // 0111 + }; virtual void injectInlineJavaScript(); virtual void paintEvent(QPaintEvent * event); diff --git a/src/domain/UBGraphicsScene.cpp b/src/domain/UBGraphicsScene.cpp index 8a69e4e0..0974105f 100644 --- a/src/domain/UBGraphicsScene.cpp +++ b/src/domain/UBGraphicsScene.cpp @@ -130,6 +130,9 @@ UBGraphicsScene::UBGraphicsScene(UBDocumentProxy* parent) UBApplication::applicationController->initialHScroll(), UBApplication::applicationController->initialVScroll())); } + + connect(this, SIGNAL(selectionChanged()), this, SLOT(selectionChangedProcessing())); + } @@ -138,6 +141,29 @@ UBGraphicsScene::~UBGraphicsScene() // NOOP } +void UBGraphicsScene::selectionChangedProcessing() +{ + QList allItemsList = items(); + for( int i = 0; i < allItemsList.size(); i++ ) + { + QGraphicsItem *nextItem = allItemsList.at(i); + qreal zValue = nextItem->zValue(); + nextItem->setZValue(qreal(1)); + qDebug() << QString(" %1 ").arg(i) << QString(" %1 ").arg(zValue); + } + + QList selItemsList = selectedItems(); + for( int i = 0; i < selItemsList.size(); i++ ) + { + QGraphicsItem *nextItem = selItemsList.at(i); + qreal zValue = nextItem->zValue(); + nextItem->setZValue(2); + qDebug() << QString(" >>> %1 <<< ").arg(i) << QString(" >>> %1 <<< ").arg(zValue); + } + + +} + // MARK: - // MARK: Mouse/Tablet events handling @@ -249,6 +275,8 @@ bool UBGraphicsScene::inputDeviceMove(const QPointF& scenePos, const qreal& pres { if (currentTool == UBStylusTool::Line) { + // TODO: Verify this beautiful implementation and check if + // it is possible to optimize it QLineF radius(mPreviousPoint, position); qreal angle = radius.angle(); angle = qRound(angle / 45) * 45; @@ -257,7 +285,7 @@ bool UBGraphicsScene::inputDeviceMove(const QPointF& scenePos, const qreal& pres mPreviousPoint.x() + radiusLength * cos((angle * PI) / 180), mPreviousPoint.y() - radiusLength * sin((angle * PI) / 180)); QLineF chord(position, newPosition); - if (chord.length() < qMin((int)16, (int)(radiusLength / 20))) + if (chord.length() < qMin((int)16, (int)(radiusLength / 20))) position = newPosition; } @@ -1074,6 +1102,8 @@ void UBGraphicsScene::addGraphicsWidget(UBGraphicsWidgetItem* graphicsWidget, co if (graphicsWidget->widgetWebView()->canBeContent()) { + graphicsWidget->widgetWebView()->loadMainHtml(); + graphicsWidget->setSelected(true); UBGraphicsItemUndoCommand* uc = new UBGraphicsItemUndoCommand(this, 0, graphicsWidget); UBApplication::undoStack->push(uc); diff --git a/src/domain/UBGraphicsScene.h b/src/domain/UBGraphicsScene.h index 3e86a4bf..e3d30af3 100644 --- a/src/domain/UBGraphicsScene.h +++ b/src/domain/UBGraphicsScene.h @@ -271,6 +271,9 @@ class UBGraphicsScene: public UBCoreGraphicsScene, public UBItem void setToolCursor(int tool); + void selectionChangedProcessing(); + + signals: void pageSizeChanged(); diff --git a/src/domain/UBW3CWidget.cpp b/src/domain/UBW3CWidget.cpp index b3fbf575..7a1af1e2 100644 --- a/src/domain/UBW3CWidget.cpp +++ b/src/domain/UBW3CWidget.cpp @@ -86,8 +86,51 @@ UBW3CWidget::UBW3CWidget(const QUrl& pWidgetUrl, QWidget *parent) QString roles = widgetElement.attribute("ub:roles", "content tool").trimmed().toLower(); - mCanBeTool = roles == "" || roles.contains("tool"); - mCanBeContent = roles == "" || roles.contains("content"); + //------------------------------// + + if( roles == "" || roles.contains("tool") ) + { + mCanBeTool = UBAbstractWidget::OSType::type_ALL; + } + + if( roles.contains("twin") ) + { + mCanBeTool |= UBAbstractWidget::OSType::type_WIN; + } + + if( roles.contains("tmac") ) + { + mCanBeTool |= UBAbstractWidget::OSType::type_MAC; + } + + if( roles.contains("tunix") ) + { + mCanBeTool |= UBAbstractWidget::OSType::type_UNIX; + } + + //---------// + + if( roles == "" || roles.contains("content") ) + { + mCanBeContent = UBAbstractWidget::OSType::type_ALL; + } + + if( roles.contains("cwin") ) + { + mCanBeContent |= UBAbstractWidget::OSType::type_WIN; + } + + if( roles.contains("cmac") ) + { + mCanBeContent |= UBAbstractWidget::OSType::type_MAC; + } + + if( roles.contains("cunix") ) + { + mCanBeContent |= UBAbstractWidget::OSType::type_UNIX; + } + + //------------------------------// QDomNodeList contentDomList = widgetElement.elementsByTagName("content"); @@ -159,8 +202,6 @@ UBW3CWidget::UBW3CWidget(const QUrl& pWidgetUrl, QWidget *parent) connect(page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(javaScriptWindowObjectCleared())); connect(UBApplication::boardController, SIGNAL(activeSceneChanged()), this, SLOT(javaScriptWindowObjectCleared())); - QWebView::load(mMainHtmlUrl); - setFixedSize(QSize(width, height)); mNominalSize = QSize(width, height); @@ -171,7 +212,6 @@ UBW3CWidget::~UBW3CWidget() // NOOP } - void UBW3CWidget::javaScriptWindowObjectCleared() { UBWidgetUniboardAPI *uniboardAPI = new UBWidgetUniboardAPI(UBApplication::boardController->activeScene(), 0); diff --git a/src/gui/UBDockPalette.cpp b/src/gui/UBDockPalette.cpp index 5a85cb9d..49fbddd6 100644 --- a/src/gui/UBDockPalette.cpp +++ b/src/gui/UBDockPalette.cpp @@ -19,9 +19,27 @@ #include "UBDockPalette.h" #include "core/UBSettings.h" #include "frameworks/UBPlatformUtils.h" +#include "core/UBApplication.h" +#include "core/UBPreferencesController.h" #include "core/memcheck.h" +/* + Note to myself: I will have to modify this implementation when we will + have to support mulitple tab. At this moment, a UBDockPalette + will be only the palette that manages the tabs. This + palette will maintain a list of tabs with icons and will + contain a QStackedWidget that will be contains the different + widget contents. + A click on a tab that is not related to the current widget + will show the related widget in the palette. + A click on a tab that is related to the current widget will + collapse the palette. + If the palette is collapsed, a click on any tab will expand it + and show the tab related widget. +*/ + + /** * \brief The constructor */ @@ -34,11 +52,12 @@ UBDockPalette::UBDockPalette(QWidget *parent, const char *name) , mResized(false) , mCollapseWidth(150) , mLastWidth(-1) + , mHTab(0) { setObjectName(name); // We let 2 pixels in order to keep a small border for the resizing - setMinimumWidth(border() + 2); + setMinimumWidth(2*border() + 2); if (parent) { @@ -61,6 +80,10 @@ UBDockPalette::UBDockPalette(QWidget *parent, const char *name) // This is the only way to set the background as transparent! setStyleSheet("QWidget {background-color: transparent}"); + + // Set the position of the tab + onToolbarPosUpdated(); + connect(UBSettings::settings()->appToolBarPositionedAtTop, SIGNAL(changed(QVariant)), this, SLOT(onToolbarPosUpdated())); } /** @@ -206,9 +229,9 @@ void UBDockPalette::mouseReleaseEvent(QMouseEvent *event) if(eUBDockOrientation_Left == mOrientation) { if(mMousePressPos.x() >= width() - 2*border() && - mMousePressPos.y() >= border() && + mMousePressPos.y() >= mHTab && mMousePressPos.x() <= width() && - mMousePressPos.y() <= border() + TABSIZE) + mMousePressPos.y() <= mHTab + TABSIZE) { tabClicked(); } @@ -217,8 +240,8 @@ void UBDockPalette::mouseReleaseEvent(QMouseEvent *event) { if(mMousePressPos.x() >= 0 && mMousePressPos.x() <= 2*border() && - mMousePressPos.y() >= border() && - mMousePressPos.y() <= border() + TABSIZE) + mMousePressPos.y() >= mHTab && + mMousePressPos.y() <= mHTab + TABSIZE) { tabClicked(); } @@ -291,23 +314,32 @@ void UBDockPalette::paintEvent(QPaintEvent *event) painter.setPen(Qt::NoPen); painter.setBrush(mBackgroundBrush); + if(eUBDockTabOrientation_Up == mTabsOrientation) + { + mHTab = border(); + } + else + { + mHTab = height() - border() - TABSIZE; + } + if(mOrientation == eUBDockOrientation_Left) { QPainterPath path; path.setFillRule(Qt::WindingFill); - path.addRect(0.0, 0.0, width()-border(), height()); - path.addRoundedRect(width()-2*border(), border(), 2*border(), TABSIZE, radius(), radius()); + path.addRect(0.0, 0.0, width()-2*border(), height()); + path.addRoundedRect(width()-4*border(), mHTab, 4*border(), TABSIZE, radius(), radius()); painter.drawPath(path); - painter.drawPixmap(width() - border() + 1, border() + 1 , border() - 4, TABSIZE - 2, mIcon); + painter.drawPixmap(width() - border() + 1, mHTab + 1 , border() - 4, TABSIZE - 2, mIcon); } else if(mOrientation == eUBDockOrientation_Right) { QPainterPath path; path.setFillRule(Qt::WindingFill); - path.addRect(border(), 0.0, width()-border(), height()); - path.addRoundedRect(0.0, border(), 2*border(), TABSIZE, radius(), radius()); + path.addRect(2*border(), 0.0, width()-2*border(), height()); + path.addRoundedRect(0.0, mHTab, 4*border(), TABSIZE, radius(), radius()); painter.drawPath(path); - painter.drawPixmap(2, border() + 1, border() - 3, TABSIZE - 2, mIcon); + painter.drawPixmap(2, mHTab + 1, border() - 3, TABSIZE - 2, mIcon); } else { @@ -372,7 +404,7 @@ void UBDockPalette::tabClicked() { // The palette must be collapsed mLastWidth = width(); - resize(border(), height()); + resize(2*border(), height()); } else { @@ -381,3 +413,27 @@ void UBDockPalette::tabClicked() mLastWidth = -1; } } + +void UBDockPalette::setTabsOrientation(eUBDockTabOrientation orientation) +{ + mTabsOrientation = orientation; +} + +void UBDockPalette::onToolbarPosUpdated() +{ + // Get the position of the tab + if(UBSettings::settings()->appToolBarPositionedAtTop->get().toBool()) + { + setTabsOrientation(eUBDockTabOrientation_Up); + } + else + { + setTabsOrientation(eUBDockTabOrientation_Down); + } + update(); +} + +int UBDockPalette::customMargin() +{ + return 5; +} diff --git a/src/gui/UBDockPalette.h b/src/gui/UBDockPalette.h index 24753f01..17440662 100644 --- a/src/gui/UBDockPalette.h +++ b/src/gui/UBDockPalette.h @@ -39,14 +39,22 @@ typedef enum eUBDockOrientation_Bottom /** [to be implemented]Bottom dock */ }eUBDockOrientation; +typedef enum +{ + eUBDockTabOrientation_Up, /** Up tabs */ + eUBDockTabOrientation_Down /** Down tabs */ +}eUBDockTabOrientation; + class UBDockPalette : public QWidget { + Q_OBJECT public: UBDockPalette(QWidget* parent=0, const char* name="UBDockPalette"); ~UBDockPalette(); eUBDockOrientation orientation(); void setOrientation(eUBDockOrientation orientation); + void setTabsOrientation(eUBDockTabOrientation orientation); virtual void mouseMoveEvent(QMouseEvent *event); virtual void mousePressEvent(QMouseEvent *event); @@ -60,6 +68,7 @@ public: protected: virtual int border(); virtual int radius(); + virtual int customMargin(); virtual void updateMaxWidth(); virtual void resizeEvent(QResizeEvent *event); virtual int collapseWidth(); @@ -86,6 +95,13 @@ protected: QPoint mMousePressPos; /** The palette icon */ QPixmap mIcon; + /** The tab orientation */ + eUBDockTabOrientation mTabsOrientation; + /** The h position of the tab */ + int mHTab; + +private slots: + void onToolbarPosUpdated(); private: void tabClicked(); diff --git a/src/gui/UBFloatingPalette.cpp b/src/gui/UBFloatingPalette.cpp index 83a85261..6be7d5bc 100644 --- a/src/gui/UBFloatingPalette.cpp +++ b/src/gui/UBFloatingPalette.cpp @@ -106,6 +106,7 @@ void UBFloatingPalette::mouseMoveEvent(QMouseEvent *event) { moveInsideParent(event->globalPos() - mDragPosition); event->accept(); + emit moving(); } else { diff --git a/src/gui/UBFloatingPalette.h b/src/gui/UBFloatingPalette.h index a7e63125..0ddc6ade 100644 --- a/src/gui/UBFloatingPalette.h +++ b/src/gui/UBFloatingPalette.h @@ -78,6 +78,7 @@ class UBFloatingPalette : public QWidget void minimizeStart(eMinimizedLocation location); void maximizeStart(); void maximized(); + void moving(); }; diff --git a/src/gui/UBLibNavigatorWidget.cpp b/src/gui/UBLibNavigatorWidget.cpp index c8a249aa..adefdd1e 100644 --- a/src/gui/UBLibNavigatorWidget.cpp +++ b/src/gui/UBLibNavigatorWidget.cpp @@ -39,6 +39,7 @@ UBLibNavigatorWidget::UBLibNavigatorWidget(QWidget *parent, const char *name):QW UBLibPalette* pLibPalette = dynamic_cast(parentWidget()); mLayout = new QVBoxLayout(this); +// mLayout->setContentsMargins(20, 5, 5, 5); setLayout(mLayout); mPathViewer = new UBLibPathViewer(this); diff --git a/src/gui/UBLibPalette.cpp b/src/gui/UBLibPalette.cpp index 656e2276..fb5c9a1f 100644 --- a/src/gui/UBLibPalette.cpp +++ b/src/gui/UBLibPalette.cpp @@ -34,13 +34,13 @@ UBLibPalette::UBLibPalette(QWidget *parent, const char *name):UBDockPalette(pare mIcon = QPixmap(":images/paletteLibrary.png"); setAcceptDrops(true); - resize(UBSettings::settings()->libPaletteWidth->get().toInt(), height()); + resize(UBSettings::settings()->libPaletteWidth->get().toInt(), parentWidget()->height()); setContentsMargins(border(), 0, 0, 0); mCollapseWidth = 180; mLastWidth = 300; mLayout = new QVBoxLayout(this); - mLayout->setMargin(3); + mLayout->setContentsMargins(20, customMargin(), customMargin(), customMargin()); setLayout(mLayout); // Build the GUI @@ -201,6 +201,7 @@ void UBLibPalette::resizeEvent(QResizeEvent *event) { UBDockPalette::resizeEvent(event); UBSettings::settings()->libPaletteWidth->set(width()); + emit resized(); } // -------------------------------------------------------------------------- diff --git a/src/gui/UBLibPalette.h b/src/gui/UBLibPalette.h index 3733610e..afbe8ff9 100644 --- a/src/gui/UBLibPalette.h +++ b/src/gui/UBLibPalette.h @@ -55,6 +55,9 @@ public: UBLibActionBar* actionBar(){return mActionBar;} +signals: + void resized(); + protected: void updateMaxWidth(); void dragEnterEvent(QDragEnterEvent* pEvent); diff --git a/src/gui/UBLibPathViewer.cpp b/src/gui/UBLibPathViewer.cpp index 1b846932..9da9c913 100644 --- a/src/gui/UBLibPathViewer.cpp +++ b/src/gui/UBLibPathViewer.cpp @@ -12,466 +12,466 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -#include -#include -#include - -#include "UBLibPathViewer.h" -#include "core/UBApplication.h" -#include "board/UBBoardController.h" - -#include "core/memcheck.h" - -/** - * \brief Constructor - * @param parent as the parent widget - * @param name as the object name - */ -UBLibPathViewer::UBLibPathViewer(QWidget *parent, const char *name):QGraphicsView(parent) - , mpElems(NULL) - , mpScene(NULL) - , mpLayout(NULL) - , mpContainer(NULL) -{ - setObjectName(name); - setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - setAcceptDrops(true); - setStyleSheet(QString("QGraphicsView{background:#EEEEEE; border-radius:10px; border:2px solid #999999;}")); - - mpScene = new UBPathScene(this); - setScene(mpScene); - - mpContainer = new QGraphicsWidget(); - mpContainer->setMinimumWidth(width() - 20); - mpScene->addItem(mpContainer); - mpLayout = new QGraphicsLinearLayout(); - mpContainer->setLayout(mpLayout); - - connect(mpScene, SIGNAL(mouseClick(UBChainedLibElement*)), this, SLOT(onMouseClicked(UBChainedLibElement*))); - connect(mpScene, SIGNAL(elementsDropped(QList,UBLibElement*)), this, SLOT(onElementsDropped(QList,UBLibElement*))); - connect(horizontalScrollBar(), SIGNAL(sliderMoved(int)), this, SLOT(onSliderMoved(int))); -} - -/** - * \brief Destructor - */ -UBLibPathViewer::~UBLibPathViewer() -{ - if(NULL != mpContainer) - { - delete mpContainer; - mpContainer = NULL; - } - //if(NULL != mpLayout) - //{ - // delete mpLayout; - // mpLayout = NULL; - //} - if(NULL != mpElems) - { - delete mpElems; - mpElems = NULL; - } - if(NULL != mpScene) - { - delete mpScene; - mpScene = NULL; - } -} - -/** - * \brief Display the current path - * @param elementsChain as the path to display - */ -void UBLibPathViewer::displayPath(UBChainedLibElement *elementsChain) -{ - if(NULL != elementsChain) - { - mpElems = elementsChain; - refreshPath(); - } -} - -/** - * \brief Refresh the current path - */ -void UBLibPathViewer::refreshPath() -{ - if (mpScene && mpContainer) - mpScene->removeItem(mpContainer); - if(mpContainer) - delete mpContainer; - mVItems.clear(); - mpScene->mapWidgetToChainedElem()->clear(); - mpContainer = new QGraphicsWidget(); - - mpScene->addItem(mpContainer); - mpLayout = new QGraphicsLinearLayout(); - mpContainer->setLayout(mpLayout); - mSceneWidth = 0; - addItem(mpElems); - mpLayout->addStretch(); - - updateScrolls(); - -} - -/** - * \brief Handle the slider moved event - * @param value as the current slider position - */ -void UBLibPathViewer::onSliderMoved(int value) -{ - Q_UNUSED(value); -} - -/** - * \brief Update the scroll bar status - */ -void UBLibPathViewer::updateScrolls() -{ - int iLimit = mSceneWidth + 40; // 2x 20 pixels margin - int iVp = viewport()->width(); - - if(iLimit >= iVp) - { - int iDiff = iLimit - iVp; - horizontalScrollBar()->setRange(0, iDiff); - } - else - { - horizontalScrollBar()->setRange(0, 0); - } -} - -/** - * \brief Append an item to the path - * @param elem as the element to add to the path - */ -void UBLibPathViewer::addItem(UBChainedLibElement *elem) -{ - if(NULL != elem) - { - // Add the icon - QLabel* pIconLabel = new QLabel(); - pIconLabel->setStyleSheet(QString("background-color: transparent;")); - pIconLabel->setPixmap((QPixmap::fromImage(*elem->element()->thumbnail())).scaledToWidth(PATHITEMWIDTH)); - UBFolderPath* iconWidget = reinterpret_cast(mpScene->addWidget(pIconLabel)); - //iconWidget->setToolTip(elem->element()->name()); - iconWidget->setWindowFlags(Qt::BypassGraphicsProxyWidget); - mpLayout->addItem(iconWidget); - mVItems << iconWidget; - mpScene->mapWidgetToChainedElem()->insert(iconWidget,elem); - mSceneWidth += pIconLabel->pixmap()->width() + 4; // 2px border - - if(NULL != elem->nextElement()) - { - // Add the arrow - QLabel* pArrowLabel = new QLabel(); - pArrowLabel->setStyleSheet(QString("background-color: transparent;")); - pArrowLabel->setPixmap(QPixmap(":images/navig_arrow.png")); - QGraphicsWidget* arrowWidget = mpScene->addWidget(pArrowLabel); - mpLayout->addItem(arrowWidget); - mVItems << arrowWidget; - mSceneWidth += pArrowLabel->pixmap()->width() + 4; // 2px border - - // Recursively call this method while a next item exists - addItem(elem->nextElement()); - } - } -} - -/** - * \brief Handles the resize event - * @param event as the resize event - */ -void UBLibPathViewer::resizeEvent(QResizeEvent *event) -{ - - if(event->oldSize() == event->size()) - event->ignore(); - else{ - if(NULL != mpContainer) - mpContainer->setMinimumWidth(width() - 20); - - viewport()->resize(width() - 10, viewport()->height()); - - updateScrolls(); - event->accept(); - } -} - -void UBLibPathViewer::showEvent(QShowEvent *event) -{ - Q_UNUSED(event); - updateScrolls(); -} - -/** - * \brief Handles the mouse move event - * @param event as the mouse move event - */ -void UBLibPathViewer::mouseMoveEvent(QMouseEvent *event) -{ - event->ignore(); -} - -void UBLibPathViewer::onMouseClicked(UBChainedLibElement *elem) -{ - emit mouseClick(elem); -} - -int UBLibPathViewer::widgetAt(QPointF p) -{ - int position = -1; - - for(int i = 0; i < mVItems.size(); i++) - { - QGraphicsWidget* pCrntWidget = mVItems.at(i); - if(NULL != pCrntWidget) - { - QRectF r = pCrntWidget->rect(); - QPointF wPos = pCrntWidget->scenePos(); - int xMin = wPos.x() + r.x(); - int xMax = wPos.x() + r.x() + r.width(); - int yMin = wPos.y() + r.y(); - int yMax = wPos.y() + r.y() + r.height(); - - if(p.x() >= xMin && - p.x() <= xMax && - p.y() >= yMin && - p.y() <= yMax) - { - return i; - } - } - } - - return position; -} - -void UBLibPathViewer::onElementsDropped(QList elements, UBLibElement *target) -{ - emit elementsDropped(elements, target); -} - - -UBFolderPath::UBFolderPath():QGraphicsProxyWidget() -{ - -} - -UBFolderPath::~UBFolderPath() -{ - -} - -/** - * \brief Handles the drag enter event - * @param pEvent as the drag enter event - */ -void UBFolderPath::dragEnterEvent(QGraphicsSceneDragDropEvent *event) -{ - event->acceptProposedAction(); -} - -/** - * \brief Handles the drop event - * @param pEvent as the drop event - */ -void UBFolderPath::dropEvent(QDropEvent *pEvent) -{ - processMimeData(pEvent->mimeData()); - pEvent->acceptProposedAction(); -} - -/** - * \brief Handles the drag move event - * @param pEvent as the drag move event - */ -void UBFolderPath::dragMoveEvent(QDragMoveEvent* pEvent) -{ - pEvent->acceptProposedAction(); -} - -/** - * \brief Process the given MIME data - * @param pData as the MIME data to process - */ -void UBFolderPath::processMimeData(const QMimeData *pData) -{ - Q_UNUSED(pData); -} - -/** - * \brief Handles the mouse press event - * @param event as the mouse press event - */ -void UBFolderPath::mousePressEvent(QGraphicsSceneMouseEvent *event) -{ - Q_UNUSED(event); -} - -/** - * \brief Handles the mouse move event - * @param event as the mouse move event - */ -void UBFolderPath::mouseMoveEvent(QMouseEvent *event) -{ - Q_UNUSED(event); -} - -/** - * \brief Handles the mouse release event - * @param event as the mouse release event - */ -void UBFolderPath::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) -{ - Q_UNUSED(event); -} - - -UBPathScene::UBPathScene(QWidget* parent):QGraphicsScene(parent) -{ - -} - -UBPathScene::~UBPathScene() -{ - -} - - -void UBPathScene::mousePressEvent(QGraphicsSceneMouseEvent *event) -{ - if(event->button() == Qt::LeftButton) - { - mDragStartPos = event->scenePos(); - mClickTime = QTime::currentTime(); - } -} - -/** - * \brief Handles the mouse release event - * @param event as the mouse release event - */ -void UBPathScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) -{ - int elapsedTimeSincePress = mClickTime.elapsed(); - - if(elapsedTimeSincePress < STARTDRAGTIME) - { - QGraphicsWidget* pGWidget = dynamic_cast(itemAt(event->pos())); - if(NULL != pGWidget) - { - // We have only one view at a time - UBLibPathViewer* pView = dynamic_cast(this->views().at(0)); - if(NULL != pView) - { - int iClickedItem = pView->widgetAt(event->scenePos()); - if(-1 != iClickedItem) - { - QGraphicsWidget* pFolderW = dynamic_cast(pGWidget->layout()->itemAt(iClickedItem)); - if(NULL != pFolderW) - { - UBChainedLibElement* chElem = mMapWidgetToChainedElem[pFolderW]; - if(NULL != chElem) - { - emit mouseClick(chElem); - } - } - } - } - } - } -} - -/** - * \brief Handles the mouse move event - * @param event as the mouse move event - */ -void UBPathScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) -{ - if(event->button() == Qt::LeftButton) - { - if((event->pos() - mDragStartPos).manhattanLength() < QApplication::startDragDistance()) - { - // The user is not doing a drag - return; - } - - // The user is performing a drag operation - QDrag* drag = new QDrag(event->widget()); - QMimeData* mimeData = new QMimeData(); - drag->setMimeData(mimeData); - drag->start(); - } -} - - -void UBPathScene::dragEnterEvent(QGraphicsSceneDragDropEvent *event) -{ - event->accept(); -} - -void UBPathScene::dragMoveEvent(QGraphicsSceneDragDropEvent *event) -{ - event->accept(); -} - -void UBPathScene::dropEvent(QGraphicsSceneDragDropEvent *event) -{ - const QMimeData* pMimeData = event->mimeData(); - qDebug() << " Drop source : " << event->source()->metaObject()->className(); - - if(0 == QString::compare(event->source()->metaObject()->className(), "UBLibraryWidget")) - { - UBLibElement* pTargetElement = elementFromPos(event->scenePos()); - if(NULL != pTargetElement) - { - if(eUBLibElementType_Folder == pTargetElement->type()) - { - // The drag comes from this application, we have now to get the list of UBLibElements* - QList qlDroppedElems; - - foreach(QUrl url, pMimeData->urls()) - qlDroppedElems << url.toString(); - - if(!qlDroppedElems.empty()) - { - // Send a signal with the target dir and the list of ublibelement* - emit elementsDropped(qlDroppedElems, pTargetElement); - } - } - } - - event->accept(); - } - else - { - event->ignore(); - } -} - -/** - * \brief Return the element related to the given position - * @param p as the given position - * - */ -UBLibElement* UBPathScene::elementFromPos(QPointF p) -{ - UBLibElement* pElem = NULL; - - QGraphicsWidget* pGWidget = dynamic_cast(itemAt(p)); - if(NULL != pGWidget) - { - UBChainedLibElement* chElem = mMapWidgetToChainedElem[pGWidget]; - if(NULL != chElem) - { - return chElem->element(); - } - } - - return pElem; -} +#include +#include +#include + +#include "UBLibPathViewer.h" +#include "core/UBApplication.h" +#include "board/UBBoardController.h" + +#include "core/memcheck.h" + +/** + * \brief Constructor + * @param parent as the parent widget + * @param name as the object name + */ +UBLibPathViewer::UBLibPathViewer(QWidget *parent, const char *name):QGraphicsView(parent) + , mpElems(NULL) + , mpScene(NULL) + , mpLayout(NULL) + , mpContainer(NULL) +{ + setObjectName(name); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + setAcceptDrops(true); + setStyleSheet(QString("QGraphicsView{background:#EEEEEE; border-radius:10px; border:2px solid #999999;}")); + + mpScene = new UBPathScene(this); + setScene(mpScene); + + mpContainer = new QGraphicsWidget(); + mpContainer->setMinimumWidth(width() - 20); + mpScene->addItem(mpContainer); + mpLayout = new QGraphicsLinearLayout(); + mpContainer->setLayout(mpLayout); + + connect(mpScene, SIGNAL(mouseClick(UBChainedLibElement*)), this, SLOT(onMouseClicked(UBChainedLibElement*))); + connect(mpScene, SIGNAL(elementsDropped(QList,UBLibElement*)), this, SLOT(onElementsDropped(QList,UBLibElement*))); + connect(horizontalScrollBar(), SIGNAL(sliderMoved(int)), this, SLOT(onSliderMoved(int))); +} + +/** + * \brief Destructor + */ +UBLibPathViewer::~UBLibPathViewer() +{ + if(NULL != mpContainer) + { + delete mpContainer; + mpContainer = NULL; + } + //if(NULL != mpLayout) + //{ + // delete mpLayout; + // mpLayout = NULL; + //} + if(NULL != mpElems) + { + delete mpElems; + mpElems = NULL; + } + if(NULL != mpScene) + { + delete mpScene; + mpScene = NULL; + } +} + +/** + * \brief Display the current path + * @param elementsChain as the path to display + */ +void UBLibPathViewer::displayPath(UBChainedLibElement *elementsChain) +{ + if(NULL != elementsChain) + { + mpElems = elementsChain; + refreshPath(); + } +} + +/** + * \brief Refresh the current path + */ +void UBLibPathViewer::refreshPath() +{ + if (mpScene && mpContainer) + mpScene->removeItem(mpContainer); + if(mpContainer) + delete mpContainer; + mVItems.clear(); + mpScene->mapWidgetToChainedElem()->clear(); + mpContainer = new QGraphicsWidget(); + + mpScene->addItem(mpContainer); + mpLayout = new QGraphicsLinearLayout(); + mpContainer->setLayout(mpLayout); + mSceneWidth = 0; + addItem(mpElems); + mpLayout->addStretch(); + + updateScrolls(); + +} + +/** + * \brief Handle the slider moved event + * @param value as the current slider position + */ +void UBLibPathViewer::onSliderMoved(int value) +{ + Q_UNUSED(value); +} + +/** + * \brief Update the scroll bar status + */ +void UBLibPathViewer::updateScrolls() +{ + int iLimit = mSceneWidth + 40; // 2x 20 pixels margin + int iVp = viewport()->width(); + + if(iLimit >= iVp) + { + int iDiff = iLimit - iVp; + horizontalScrollBar()->setRange(0, iDiff); + } + else + { + horizontalScrollBar()->setRange(0, 0); + } +} + +/** + * \brief Append an item to the path + * @param elem as the element to add to the path + */ +void UBLibPathViewer::addItem(UBChainedLibElement *elem) +{ + if(NULL != elem) + { + // Add the icon + QLabel* pIconLabel = new QLabel(); + pIconLabel->setStyleSheet(QString("background-color: transparent;")); + pIconLabel->setPixmap((QPixmap::fromImage(*elem->element()->thumbnail())).scaledToWidth(PATHITEMWIDTH)); + UBFolderPath* iconWidget = reinterpret_cast(mpScene->addWidget(pIconLabel)); + //iconWidget->setToolTip(elem->element()->name()); + iconWidget->setWindowFlags(Qt::BypassGraphicsProxyWidget); + mpLayout->addItem(iconWidget); + mVItems << iconWidget; + mpScene->mapWidgetToChainedElem()->insert(iconWidget,elem); + mSceneWidth += pIconLabel->pixmap()->width() + 4; // 2px border + + if(NULL != elem->nextElement()) + { + // Add the arrow + QLabel* pArrowLabel = new QLabel(); + pArrowLabel->setStyleSheet(QString("background-color: transparent;")); + pArrowLabel->setPixmap(QPixmap(":images/navig_arrow.png")); + QGraphicsWidget* arrowWidget = mpScene->addWidget(pArrowLabel); + mpLayout->addItem(arrowWidget); + mVItems << arrowWidget; + mSceneWidth += pArrowLabel->pixmap()->width() + 4; // 2px border + + // Recursively call this method while a next item exists + addItem(elem->nextElement()); + } + } +} + +/** + * \brief Handles the resize event + * @param event as the resize event + */ +void UBLibPathViewer::resizeEvent(QResizeEvent *event) +{ + + if(event->oldSize() == event->size()) + event->ignore(); + else{ + if(NULL != mpContainer) + mpContainer->setMinimumWidth(width() - 20); + + viewport()->resize(width() - 10, viewport()->height()); + + updateScrolls(); + event->accept(); + } +} + +void UBLibPathViewer::showEvent(QShowEvent *event) +{ + Q_UNUSED(event); + updateScrolls(); +} + +/** + * \brief Handles the mouse move event + * @param event as the mouse move event + */ +void UBLibPathViewer::mouseMoveEvent(QMouseEvent *event) +{ + event->ignore(); +} + +void UBLibPathViewer::onMouseClicked(UBChainedLibElement *elem) +{ + emit mouseClick(elem); +} + +int UBLibPathViewer::widgetAt(QPointF p) +{ + int position = -1; + + for(int i = 0; i < mVItems.size(); i++) + { + QGraphicsWidget* pCrntWidget = mVItems.at(i); + if(NULL != pCrntWidget) + { + QRectF r = pCrntWidget->rect(); + QPointF wPos = pCrntWidget->scenePos(); + int xMin = wPos.x() + r.x(); + int xMax = wPos.x() + r.x() + r.width(); + int yMin = wPos.y() + r.y(); + int yMax = wPos.y() + r.y() + r.height(); + + if(p.x() >= xMin && + p.x() <= xMax && + p.y() >= yMin && + p.y() <= yMax) + { + return i; + } + } + } + + return position; +} + +void UBLibPathViewer::onElementsDropped(QList elements, UBLibElement *target) +{ + emit elementsDropped(elements, target); +} + + +UBFolderPath::UBFolderPath():QGraphicsProxyWidget() +{ + +} + +UBFolderPath::~UBFolderPath() +{ + +} + +/** + * \brief Handles the drag enter event + * @param pEvent as the drag enter event + */ +void UBFolderPath::dragEnterEvent(QGraphicsSceneDragDropEvent *event) +{ + event->acceptProposedAction(); +} + +/** + * \brief Handles the drop event + * @param pEvent as the drop event + */ +void UBFolderPath::dropEvent(QDropEvent *pEvent) +{ + processMimeData(pEvent->mimeData()); + pEvent->acceptProposedAction(); +} + +/** + * \brief Handles the drag move event + * @param pEvent as the drag move event + */ +void UBFolderPath::dragMoveEvent(QDragMoveEvent* pEvent) +{ + pEvent->acceptProposedAction(); +} + +/** + * \brief Process the given MIME data + * @param pData as the MIME data to process + */ +void UBFolderPath::processMimeData(const QMimeData *pData) +{ + Q_UNUSED(pData); +} + +/** + * \brief Handles the mouse press event + * @param event as the mouse press event + */ +void UBFolderPath::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event); +} + +/** + * \brief Handles the mouse move event + * @param event as the mouse move event + */ +void UBFolderPath::mouseMoveEvent(QMouseEvent *event) +{ + Q_UNUSED(event); +} + +/** + * \brief Handles the mouse release event + * @param event as the mouse release event + */ +void UBFolderPath::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_UNUSED(event); +} + + +UBPathScene::UBPathScene(QWidget* parent):QGraphicsScene(parent) +{ + +} + +UBPathScene::~UBPathScene() +{ + +} + + +void UBPathScene::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + if(event->button() == Qt::LeftButton) + { + mDragStartPos = event->scenePos(); + mClickTime = QTime::currentTime(); + } +} + +/** + * \brief Handles the mouse release event + * @param event as the mouse release event + */ +void UBPathScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + int elapsedTimeSincePress = mClickTime.elapsed(); + + if(elapsedTimeSincePress < STARTDRAGTIME) + { + QGraphicsWidget* pGWidget = dynamic_cast(itemAt(event->pos())); + if(NULL != pGWidget) + { + // We have only one view at a time + UBLibPathViewer* pView = dynamic_cast(this->views().at(0)); + if(NULL != pView) + { + int iClickedItem = pView->widgetAt(event->scenePos()); + if(-1 != iClickedItem) + { + QGraphicsWidget* pFolderW = dynamic_cast(pGWidget->layout()->itemAt(iClickedItem)); + if(NULL != pFolderW) + { + UBChainedLibElement* chElem = mMapWidgetToChainedElem[pFolderW]; + if(NULL != chElem) + { + emit mouseClick(chElem); + } + } + } + } + } + } +} + +/** + * \brief Handles the mouse move event + * @param event as the mouse move event + */ +void UBPathScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + if(event->button() == Qt::LeftButton) + { + if((event->pos() - mDragStartPos).manhattanLength() < QApplication::startDragDistance()) + { + // The user is not doing a drag + return; + } + + // The user is performing a drag operation + QDrag* drag = new QDrag(event->widget()); + QMimeData* mimeData = new QMimeData(); + drag->setMimeData(mimeData); + drag->start(); + } +} + + +void UBPathScene::dragEnterEvent(QGraphicsSceneDragDropEvent *event) +{ + event->accept(); +} + +void UBPathScene::dragMoveEvent(QGraphicsSceneDragDropEvent *event) +{ + event->accept(); +} + +void UBPathScene::dropEvent(QGraphicsSceneDragDropEvent *event) +{ + const QMimeData* pMimeData = event->mimeData(); + qDebug() << " Drop source : " << event->source()->metaObject()->className(); + + if(0 == QString::compare(event->source()->metaObject()->className(), "UBLibraryWidget")) + { + UBLibElement* pTargetElement = elementFromPos(event->scenePos()); + if(NULL != pTargetElement) + { + if(eUBLibElementType_Folder == pTargetElement->type()) + { + // The drag comes from this application, we have now to get the list of UBLibElements* + QList qlDroppedElems; + + foreach(QUrl url, pMimeData->urls()) + qlDroppedElems << url.toString(); + + if(!qlDroppedElems.empty()) + { + // Send a signal with the target dir and the list of ublibelement* + emit elementsDropped(qlDroppedElems, pTargetElement); + } + } + } + + event->accept(); + } + else + { + event->ignore(); + } +} + +/** + * \brief Return the element related to the given position + * @param p as the given position + * + */ +UBLibElement* UBPathScene::elementFromPos(QPointF p) +{ + UBLibElement* pElem = NULL; + + QGraphicsWidget* pGWidget = dynamic_cast(itemAt(p)); + if(NULL != pGWidget) + { + UBChainedLibElement* chElem = mMapWidgetToChainedElem[pGWidget]; + if(NULL != chElem) + { + return chElem->element(); + } + } + + return pElem; +} diff --git a/src/gui/UBNavigatorPalette.cpp b/src/gui/UBNavigatorPalette.cpp index 2ed1e6e9..8ac69e5e 100644 --- a/src/gui/UBNavigatorPalette.cpp +++ b/src/gui/UBNavigatorPalette.cpp @@ -35,11 +35,10 @@ UBNavigatorPalette::UBNavigatorPalette(QWidget *parent, const char *name):UBDock mIcon = QPixmap(":images/paletteNavigator.png"); resize(UBSettings::settings()->navigPaletteWidth->get().toInt(), height()); mLastWidth = 300; - setContentsMargins(0, 0, border(), 0); // Build the gui mLayout = new QVBoxLayout(this); - mLayout->setMargin(3); + mLayout->setContentsMargins(customMargin(), customMargin(), 2*border() + customMargin(), customMargin()); setLayout(mLayout); mNavigator = new UBDocumentNavigator(this); diff --git a/src/gui/UBToolWidget.cpp b/src/gui/UBToolWidget.cpp index 59ff2af4..ea1bdee1 100644 --- a/src/gui/UBToolWidget.cpp +++ b/src/gui/UBToolWidget.cpp @@ -72,6 +72,7 @@ UBToolWidget::UBToolWidget(UBAbstractWidget* pWidget, QWidget* pParent) , mShouldMoveWidget(false) { mToolWidget->setParent(this); + mToolWidget->loadMainHtml(); initialize(); diff --git a/src/pdf/PDFRenderer.cpp b/src/pdf/PDFRenderer.cpp index a7a8c793..57e9b36d 100644 --- a/src/pdf/PDFRenderer.cpp +++ b/src/pdf/PDFRenderer.cpp @@ -30,7 +30,7 @@ PDFRenderer::~PDFRenderer() // NOOP } -PDFRenderer* PDFRenderer::rendererForUuid(const QUuid &uuid, const QString &filename) +PDFRenderer* PDFRenderer::rendererForUuid(const QUuid &uuid, const QString &filename, bool importingFile) { if (sRenderers.contains(uuid)) { @@ -38,7 +38,7 @@ PDFRenderer* PDFRenderer::rendererForUuid(const QUuid &uuid, const QString &file } else { - PDFRenderer *newRenderer = new XPDFRenderer(filename); + PDFRenderer *newRenderer = new XPDFRenderer(filename,importingFile); newRenderer->setRefCount(0); newRenderer->setFileUuid(uuid); diff --git a/src/pdf/PDFRenderer.h b/src/pdf/PDFRenderer.h index 5f68ed28..63945cd1 100644 --- a/src/pdf/PDFRenderer.h +++ b/src/pdf/PDFRenderer.h @@ -31,7 +31,7 @@ class PDFRenderer : public QObject Q_OBJECT public: - static PDFRenderer* rendererForUuid(const QUuid &uuid, const QString &filename); + static PDFRenderer* rendererForUuid(const QUuid &uuid, const QString &filename, bool importingFile = false); virtual ~PDFRenderer(); virtual bool isValid() const = 0; diff --git a/src/pdf/XPDFRenderer.cpp b/src/pdf/XPDFRenderer.cpp index 30717935..5ef2851b 100644 --- a/src/pdf/XPDFRenderer.cpp +++ b/src/pdf/XPDFRenderer.cpp @@ -19,18 +19,11 @@ #include -#include -#include -#include -#include -#include - - #include "core/memcheck.h" QAtomicInt XPDFRenderer::sInstancesCount = 0; -XPDFRenderer::XPDFRenderer(const QString &filename) +XPDFRenderer::XPDFRenderer(const QString &filename, bool importingFile) : mDocument(0) { if (!globalParams) @@ -44,7 +37,13 @@ XPDFRenderer::XPDFRenderer(const QString &filename) mDocument = new PDFDoc(new GString(filename.toUtf8().data()), 0, 0, 0); // the filename GString is deleted on PDFDoc desctruction sInstancesCount.ref(); - + bThumbGenerated = !importingFile; + bPagesGenerated = false; + mPagesMap.clear(); + mThumbs.clear(); + mThumbMap.clear(); + mScaleX = 0.0; + mScaleY = 0.0; } XPDFRenderer::~XPDFRenderer() @@ -135,47 +134,114 @@ int XPDFRenderer::pageRotation(int pageNumber) const return 0; } - void XPDFRenderer::render(QPainter *p, int pageNumber, const QRectF &bounds) { + if (isValid()) + { + qreal xscale = p->worldTransform().m11(); + qreal yscale = p->worldTransform().m22(); + bool bZoomChanged = false; + bool bFirstThumbnail = false; + + if(fabs(mScaleX - xscale) > 0.1 || fabs(mScaleY - yscale) > 0.1) + { + mScaleX = xscale; + mScaleY = yscale; + bZoomChanged = true; + } + + // First verify if the thumbnails and the pages are generated + if(!bThumbGenerated) + { + if(pageNumber == 1) + { + bFirstThumbnail = true; + } + + if(!mThumbMap[pageNumber - 1]) + { + + // Generate the thumbnail + mThumbs << *createPDFImage(pageNumber, xscale, yscale, bounds); + mThumbMap[pageNumber - 1] = true; + if(pageNumber == mDocument->getNumPages()) + { + bThumbGenerated = true; + } + } + } + else if(!bPagesGenerated || bZoomChanged) + { + if(!mPagesMap[pageNumber - 1] || bZoomChanged) + { + // Generate the page + mNumPageToPageMap[pageNumber] = *createPDFImage(pageNumber, xscale, yscale, bounds); + mPagesMap[pageNumber - 1] = true; + if(mPagesMap.size() == mDocument->getNumPages()) + { + bPagesGenerated = true; + } + } + } + + QImage pdfImage; + + if(!bThumbGenerated || bFirstThumbnail) + { + pdfImage = mThumbs.at(pageNumber - 1); + } + else + { + pdfImage = mNumPageToPageMap[pageNumber]; + } + + QTransform savedTransform = p->worldTransform(); + p->resetTransform(); + QTime t; + t.start(); + p->drawImage(QPointF(savedTransform.dx() + mSliceX, savedTransform.dy() + mSliceY), pdfImage); + //qDebug() << "XPDFRenderer::render(...) execution time: " << t.elapsed() << "ms"; + p->setWorldTransform(savedTransform); + } +} + +QImage* XPDFRenderer::createPDFImage(int pageNumber, const qreal xscale, const qreal yscale, const QRectF &bounds) +{ + QImage* img = new QImage(); if (isValid()) { SplashColor paperColor = {0xFF, 0xFF, 0xFF}; // white - SplashOutputDev splash(splashModeRGB8, 1, gFalse, paperColor); - splash.startDoc(mDocument->getXRef()); + mSplash = new SplashOutputDev(splashModeRGB8, 1, gFalse, paperColor); + mSplash->startDoc(mDocument->getXRef()); int hResolution = 72; int vResolution = 72; int rotation = 0; // in degrees (get it from the worldTransform if we want to support rotation) GBool useMediaBox = gFalse; GBool crop = gTrue; GBool printing = gFalse; - const qreal xScale = p->worldTransform().m11(); - const qreal yScale = p->worldTransform().m22(); - qreal sliceX = 0.; - qreal sliceY = 0.; + const qreal xScale = xscale; + const qreal yScale = yscale; + mSliceX = 0.; + mSliceY = 0.; if (bounds.isNull()) { - mDocument->displayPage(&splash, pageNumber, hResolution * xScale, vResolution * yScale, + mDocument->displayPage(mSplash, pageNumber, hResolution * xScale, vResolution * yScale, rotation, useMediaBox, crop, printing); } else { - sliceX = bounds.x() * xScale; - sliceY = bounds.y() * yScale; + mSliceX = bounds.x() * xScale; + mSliceY = bounds.y() * yScale; qreal sliceW = bounds.width() * xScale; qreal sliceH = bounds.height() * yScale; - mDocument->displayPageSlice(&splash, pageNumber, hResolution * xScale, vResolution * yScale, - rotation, useMediaBox, crop, printing, sliceX, sliceY, sliceW, sliceH); + mDocument->displayPageSlice(mSplash, pageNumber, hResolution * xScale, vResolution * yScale, + rotation, useMediaBox, crop, printing, mSliceX, mSliceY, sliceW, sliceH); } - SplashBitmap *bitmap = splash.getBitmap(); - QImage pdfImage(bitmap->getDataPtr(), bitmap->getWidth(), bitmap->getHeight(), bitmap->getWidth() * 3, QImage::Format_RGB888); - - QTransform savedTransform = p->worldTransform(); - p->resetTransform(); - p->drawImage(QPointF(savedTransform.dx() + sliceX, savedTransform.dy() + sliceY), pdfImage); - p->setWorldTransform(savedTransform); + mpSplashBitmap = mSplash->getBitmap(); + img = new QImage(mpSplashBitmap->getDataPtr(), mpSplashBitmap->getWidth(), mpSplashBitmap->getHeight(), mpSplashBitmap->getWidth() * 3, QImage::Format_RGB888); } -} \ No newline at end of file + return img; +} diff --git a/src/pdf/XPDFRenderer.h b/src/pdf/XPDFRenderer.h index 5b2dedcc..63d4bbd4 100644 --- a/src/pdf/XPDFRenderer.h +++ b/src/pdf/XPDFRenderer.h @@ -30,7 +30,7 @@ class XPDFRenderer : public PDFRenderer Q_OBJECT public: - XPDFRenderer(const QString &filename); + XPDFRenderer(const QString &filename, bool importingFile = false); virtual ~XPDFRenderer(); bool isValid() const; diff --git a/src/tools/UBGraphicsTriangle.cpp b/src/tools/UBGraphicsTriangle.cpp index b617740b..44c504f2 100644 --- a/src/tools/UBGraphicsTriangle.cpp +++ b/src/tools/UBGraphicsTriangle.cpp @@ -29,28 +29,28 @@ const UBGraphicsTriangle::UBGraphicsTriangleOrientation UBGraphicsTriangle::sDef UBGraphicsTriangle::BottomLeft; UBGraphicsTriangle::UBGraphicsTriangle() - : QGraphicsPolygonItem() - , UBAbstractDrawRuler() - , mResizing1(false) - , mResizing2(false) - , mRotating(false) + : QGraphicsPolygonItem() + , UBAbstractDrawRuler() + , mResizing1(false) + , mResizing2(false) + , mRotating(false) , angle(0) { - setRect(sDefaultRect, sDefaultOrientation); + setRect(sDefaultRect, sDefaultOrientation); - create(*this); + create(*this); - mHFlipSvgItem = new QGraphicsSvgItem(":/images/hflipTool.svg", this); + mHFlipSvgItem = new QGraphicsSvgItem(":/images/hflipTool.svg", this); mHFlipSvgItem->setVisible(false); mHFlipSvgItem->setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Control)); - mVFlipSvgItem = new QGraphicsSvgItem(":/images/vflipTool.svg", this); + mVFlipSvgItem = new QGraphicsSvgItem(":/images/vflipTool.svg", this); mVFlipSvgItem->setVisible(false); mVFlipSvgItem->setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Control)); - mRotateSvgItem = new QGraphicsSvgItem(":/images/rotateTool.svg", this); + mRotateSvgItem = new QGraphicsSvgItem(":/images/rotateTool.svg", this); mRotateSvgItem->setVisible(false); mRotateSvgItem->setData(UBGraphicsItemData::ItemLayerType, QVariant(UBItemLayerType::Control)); @@ -89,10 +89,10 @@ UBGraphicsTriangle::~UBGraphicsTriangle() UBItem* UBGraphicsTriangle::deepCopy(void) const { - UBGraphicsTriangle* copy = new UBGraphicsTriangle(); + UBGraphicsTriangle* copy = new UBGraphicsTriangle(); copy->setPos(this->pos()); - copy->setPolygon(this->polygon()); + copy->setPolygon(this->polygon()); copy->setZValue(this->zValue()); copy->setTransform(this->transform()); @@ -104,11 +104,11 @@ UBItem* UBGraphicsTriangle::deepCopy(void) const void UBGraphicsTriangle::setRect(qreal x, qreal y, qreal w, qreal h, UBGraphicsTriangleOrientation orientation) { - QPolygonF polygon; - polygon << QPointF(x, y) << QPoint(x, y + h) << QPoint(x+w, y + h); - setPolygon(polygon); + QPolygonF polygon; + polygon << QPointF(x, y) << QPoint(x, y + h) << QPoint(x+w, y + h); + setPolygon(polygon); - setOrientation(orientation); + setOrientation(orientation); } void UBGraphicsTriangle::setOrientation(UBGraphicsTriangleOrientation orientation) @@ -123,7 +123,7 @@ void UBGraphicsTriangle::setOrientation(UBGraphicsTriangleOrientation orientatio UBGraphicsScene* UBGraphicsTriangle::scene() const { - return static_cast(QGraphicsPolygonItem::scene()); + return static_cast(QGraphicsPolygonItem::scene()); } void UBGraphicsTriangle::calculatePoints(const QRectF& r) @@ -152,9 +152,9 @@ void UBGraphicsTriangle::calculatePoints(const QRectF& r) break; } - C = sqrt(rect().width() * rect().width() + rect().height() * rect().height()); - qreal L = (C * d + rect().width() * d)/ rect().height(); - qreal K = (C * d + rect().height() * d)/ rect().width(); + C = sqrt(rect().width() * rect().width() + rect().height() * rect().height()); + qreal L = (C * d + rect().width() * d)/ rect().height(); + qreal K = (C * d + rect().height() * d)/ rect().width(); switch(mOrientation) { @@ -179,8 +179,8 @@ void UBGraphicsTriangle::calculatePoints(const QRectF& r) C2.setX(r.left() + L); C2.setY(r.bottom() - d); break; } - W1 = rect().height() * d / C; - H1 = rect().width() * d / C; + W1 = rect().height() * d / C; + H1 = rect().width() * d / C; switch(mOrientation) { @@ -202,69 +202,69 @@ void UBGraphicsTriangle::calculatePoints(const QRectF& r) void UBGraphicsTriangle::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { - painter->setPen(Qt::NoPen); - - QPolygonF polygon; - - QLinearGradient gradient1(QPointF(A1.x(), 0), QPointF(A2.x(), 0)); - gradient1.setColorAt(0, edgeFillColor()); - gradient1.setColorAt(1, middleFillColor()); - painter->setBrush(gradient1); - polygon << A1 << A2 << B2 << B1; - painter->drawPolygon(polygon); - polygon.clear(); - - QLinearGradient gradient2(QPointF(0, B1.y()), QPointF(0, B2.y())); - gradient2.setColorAt(0, edgeFillColor()); - gradient2.setColorAt(1, middleFillColor()); - painter->setBrush(gradient2); - polygon << B1 << B2 << C2 << C1; - painter->drawPolygon(polygon); - polygon.clear(); - - QLinearGradient gradient3(CC, C2); - gradient3.setColorAt(0, edgeFillColor()); - gradient3.setColorAt(1, middleFillColor()); - painter->setBrush(gradient3); - polygon << C1 << C2 << A2 << A1; - painter->drawPolygon(polygon); - polygon.clear(); + painter->setPen(Qt::NoPen); + QPolygonF polygon; - painter->setBrush(Qt::NoBrush); - painter->setPen(drawColor()); + QLinearGradient gradient1(QPointF(A1.x(), 0), QPointF(A2.x(), 0)); + gradient1.setColorAt(0, edgeFillColor()); + gradient1.setColorAt(1, middleFillColor()); + painter->setBrush(gradient1); + polygon << A1 << A2 << B2 << B1; + painter->drawPolygon(polygon); + polygon.clear(); + + QLinearGradient gradient2(QPointF(0, B1.y()), QPointF(0, B2.y())); + gradient2.setColorAt(0, edgeFillColor()); + gradient2.setColorAt(1, middleFillColor()); + painter->setBrush(gradient2); + polygon << B1 << B2 << C2 << C1; + painter->drawPolygon(polygon); + polygon.clear(); + + QLinearGradient gradient3(CC, C2); + gradient3.setColorAt(0, edgeFillColor()); + gradient3.setColorAt(1, middleFillColor()); + painter->setBrush(gradient3); + polygon << C1 << C2 << A2 << A1; + painter->drawPolygon(polygon); + polygon.clear(); + + + painter->setBrush(Qt::NoBrush); + painter->setPen(drawColor()); - polygon << A1 << B1 << C1; - painter->drawPolygon(polygon); - polygon.clear(); + polygon << A1 << B1 << C1; + painter->drawPolygon(polygon); + polygon.clear(); - polygon << A2 << B2 << C2; - painter->drawPolygon(polygon); + polygon << A2 << B2 << C2; + painter->drawPolygon(polygon); - paintGraduations(painter); + paintGraduations(painter); - mAntiScaleRatio = 1 / (UBApplication::boardController->systemScaleFactor() * UBApplication::boardController->currentZoom()); + mAntiScaleRatio = 1 / (UBApplication::boardController->systemScaleFactor() * UBApplication::boardController->currentZoom()); QTransform antiScaleTransform; antiScaleTransform.scale(mAntiScaleRatio, mAntiScaleRatio); mCloseSvgItem->setTransform(antiScaleTransform); - mHFlipSvgItem->setTransform(antiScaleTransform); - mVFlipSvgItem->setTransform(antiScaleTransform); - mRotateSvgItem->setTransform(antiScaleTransform); + mHFlipSvgItem->setTransform(antiScaleTransform); + mVFlipSvgItem->setTransform(antiScaleTransform); + mRotateSvgItem->setTransform(antiScaleTransform); mCloseSvgItem->setPos(closeButtonRect().topLeft()); - mHFlipSvgItem->setPos(hFlipRect().topLeft()); - mVFlipSvgItem->setPos(vFlipRect().topLeft()); - mRotateSvgItem->setPos(rotateRect().topLeft()); - - if (mShowButtons || mResizing1 || mResizing2) - { - painter->setBrush(QColor(0, 0, 0)); - if (mShowButtons || mResizing1) - painter->drawPolygon(resize1Polygon()); - if (mShowButtons || mResizing2) - painter->drawPolygon(resize2Polygon()); - } + mHFlipSvgItem->setPos(hFlipRect().topLeft()); + mVFlipSvgItem->setPos(vFlipRect().topLeft()); + mRotateSvgItem->setPos(rotateRect().topLeft()); + + if (mShowButtons || mResizing1 || mResizing2) + { + painter->setBrush(QColor(0, 0, 0)); + if (mShowButtons || mResizing1) + painter->drawPolygon(resize1Polygon()); + if (mShowButtons || mResizing2) + painter->drawPolygon(resize2Polygon()); + } } void UBGraphicsTriangle::paintGraduations(QPainter *painter) @@ -289,29 +289,29 @@ void UBGraphicsTriangle::paintGraduations(QPainter *painter) ((0 == millimeters % millimetersPerHalfCentimeter) ? halfCentimeterGraduationHeight : millimeterGraduationHeight); - // Check that grad. line inside triangle + // Check that grad. line inside triangle qreal dx = (kx > 0) ? rect().width() - graduationX : graduationX - rect().x(); qreal lineY = rotationCenter().y() - ky * rect().height()/rect().width() * dx; if (mOrientation == BottomLeft || mOrientation == BottomRight) { - if (lineY >= rotationCenter().y() - ky * graduationHeight) - break; + if (lineY >= rotationCenter().y() - ky * graduationHeight) + break; } else { - if (lineY <= rotationCenter().y() - ky * graduationHeight) - break; + if (lineY <= rotationCenter().y() - ky * graduationHeight) + break; } painter->drawLine(QLine(graduationX, rotationCenter().y(), graduationX, rotationCenter().y() - ky * graduationHeight)); if (0 == millimeters % millimetersPerCentimeter) { QString text = QString("%1").arg((int)(millimeters / millimetersPerCentimeter)); - int textXRight = graduationX + fontMetrics.width(text) / 2; - qreal textWidth = fontMetrics.width(text); + int textXRight = graduationX + fontMetrics.width(text) / 2; + qreal textWidth = fontMetrics.width(text); qreal textHeight = fontMetrics.tightBoundingRect(text).height() + 5; - int textY = (ky > 0) ? rotationCenter().y() - 5 - centimeterGraduationHeight - textHeight + int textY = (ky > 0) ? rotationCenter().y() - 5 - centimeterGraduationHeight - textHeight : rotationCenter().y() + 5 + centimeterGraduationHeight; bool bText = false; @@ -342,7 +342,7 @@ void UBGraphicsTriangle::paintGraduations(QPainter *painter) if (bText) painter->drawText( QRectF(graduationX - textWidth / 2, - textY, textWidth, textHeight), + textY, textWidth, textHeight), Qt::AlignVCenter, text); } @@ -369,7 +369,7 @@ void UBGraphicsTriangle::rotateAroundCenter(QTransform& transform, QPointF cente } -QPointF UBGraphicsTriangle::rotationCenter() const +QPointF UBGraphicsTriangle::rotationCenter() const { switch(mOrientation) { @@ -383,30 +383,30 @@ QPointF UBGraphicsTriangle::rotationCenter() const return QPointF(0, 0); } -QRectF UBGraphicsTriangle::closeButtonRect() const +QRectF UBGraphicsTriangle::closeButtonRect() const { switch(mOrientation) { case BottomLeft: return QRectF(B2.x() - mCloseSvgItem->boundingRect().width() - 5, - B2.y() - mCloseSvgItem->boundingRect().height() - 5, - mCloseSvgItem->boundingRect().width(), - mCloseSvgItem->boundingRect().height()); + B2.y() - mCloseSvgItem->boundingRect().height() - 5, + mCloseSvgItem->boundingRect().width(), + mCloseSvgItem->boundingRect().height()); case TopLeft: return QRectF(B2.x() - mCloseSvgItem->boundingRect().width() - 5, - B2.y() + 5, - mCloseSvgItem->boundingRect().width(), - mCloseSvgItem->boundingRect().height()); + B2.y() + 5, + mCloseSvgItem->boundingRect().width(), + mCloseSvgItem->boundingRect().height()); case TopRight: return QRectF(B2.x() + 5, - B2.y() + 5, - mCloseSvgItem->boundingRect().width(), - mCloseSvgItem->boundingRect().height()); + B2.y() + 5, + mCloseSvgItem->boundingRect().width(), + mCloseSvgItem->boundingRect().height()); case BottomRight: return QRectF(B2.x() + 5, - B2.y() - mCloseSvgItem->boundingRect().height() - 5, - mCloseSvgItem->boundingRect().width(), - mCloseSvgItem->boundingRect().height()); + B2.y() - mCloseSvgItem->boundingRect().height() - 5, + mCloseSvgItem->boundingRect().width(), + mCloseSvgItem->boundingRect().height()); } return QRectF(0,0,0,0); } @@ -435,9 +435,9 @@ QPolygonF UBGraphicsTriangle::resize1Polygon() const } QPointF P1(C1.x() + x1 * sArrowLength, C1.y()); QPointF P2(C1.x() + x1 * sArrowLength * rect().width()/C, C1.y() + y1 * sArrowLength * rect().height() / C); - QPolygonF p; - p << C1 << P1 << P2; - return p; + QPolygonF p; + p << C1 << P1 << P2; + return p; } QPolygonF UBGraphicsTriangle::resize2Polygon() const @@ -465,70 +465,70 @@ QPolygonF UBGraphicsTriangle::resize2Polygon() const QPointF P1(A1.x(), A1.y() + y1 * sArrowLength); QPointF P2(A1.x() + x1 * sArrowLength * rect().width()/C, A1.y() + y1 * sArrowLength * rect().height() / C); - QPolygonF p; - p << A1 << P1 << P2; - return p; + QPolygonF p; + p << A1 << P1 << P2; + return p; } -QRectF UBGraphicsTriangle::hFlipRect() const +QRectF UBGraphicsTriangle::hFlipRect() const { qreal dy = mVFlipSvgItem->boundingRect().height() + mCloseSvgItem->boundingRect().height() + 10; switch(mOrientation) { case BottomLeft: return QRectF(B2.x() - mHFlipSvgItem->boundingRect().width() - 5, - B2.y() - mHFlipSvgItem->boundingRect().height() - 5 - dy, + B2.y() - mHFlipSvgItem->boundingRect().height() - 5 - dy, mHFlipSvgItem->boundingRect().width(), - mHFlipSvgItem->boundingRect().height()); + mHFlipSvgItem->boundingRect().height()); case TopLeft: return QRectF(B2.x() - mHFlipSvgItem->boundingRect().width() - 5, - B2.y() + 5 + dy, - mHFlipSvgItem->boundingRect().width(), - mHFlipSvgItem->boundingRect().height()); + B2.y() + 5 + dy, + mHFlipSvgItem->boundingRect().width(), + mHFlipSvgItem->boundingRect().height()); case TopRight: return QRectF(B2.x() + 5, - B2.y() + 5 + dy, - mHFlipSvgItem->boundingRect().width(), - mHFlipSvgItem->boundingRect().height()); + B2.y() + 5 + dy, + mHFlipSvgItem->boundingRect().width(), + mHFlipSvgItem->boundingRect().height()); case BottomRight: return QRectF(B2.x() + 5, - B2.y() - mHFlipSvgItem->boundingRect().height() - 5 - dy, - mHFlipSvgItem->boundingRect().width(), - mHFlipSvgItem->boundingRect().height()); + B2.y() - mHFlipSvgItem->boundingRect().height() - 5 - dy, + mHFlipSvgItem->boundingRect().width(), + mHFlipSvgItem->boundingRect().height()); } return QRectF(0,0,0,0); } -QRectF UBGraphicsTriangle::vFlipRect() const +QRectF UBGraphicsTriangle::vFlipRect() const { qreal dy = mCloseSvgItem->boundingRect().height() + 5; switch(mOrientation) { case BottomLeft: return QRectF(B2.x() - mVFlipSvgItem->boundingRect().width() - 5, - B2.y() - mVFlipSvgItem->boundingRect().height() - 5 - dy, + B2.y() - mVFlipSvgItem->boundingRect().height() - 5 - dy, mVFlipSvgItem->boundingRect().width(), - mVFlipSvgItem->boundingRect().height()); + mVFlipSvgItem->boundingRect().height()); case TopLeft: return QRectF(B2.x() - mVFlipSvgItem->boundingRect().width() - 5, - B2.y() + 5 + dy, - mVFlipSvgItem->boundingRect().width(), - mVFlipSvgItem->boundingRect().height()); + B2.y() + 5 + dy, + mVFlipSvgItem->boundingRect().width(), + mVFlipSvgItem->boundingRect().height()); case TopRight: return QRectF(B2.x() + 5, - B2.y() + 5 + dy, - mVFlipSvgItem->boundingRect().width(), - mVFlipSvgItem->boundingRect().height()); + B2.y() + 5 + dy, + mVFlipSvgItem->boundingRect().width(), + mVFlipSvgItem->boundingRect().height()); case BottomRight: return QRectF(B2.x() + 5, - B2.y() - mVFlipSvgItem->boundingRect().height() - 5 - dy, - mVFlipSvgItem->boundingRect().width(), - mVFlipSvgItem->boundingRect().height()); + B2.y() - mVFlipSvgItem->boundingRect().height() - 5 - dy, + mVFlipSvgItem->boundingRect().width(), + mVFlipSvgItem->boundingRect().height()); } return QRectF(0,0,0,0); } -QRectF UBGraphicsTriangle::rotateRect() const +QRectF UBGraphicsTriangle::rotateRect() const { QPointF p(C2); switch(mOrientation) @@ -546,122 +546,124 @@ QRectF UBGraphicsTriangle::rotateRect() const p += QPointF(-20 - mRotateSvgItem->boundingRect().width(), 5); break; } - return QRectF(p, QSizeF(mRotateSvgItem->boundingRect().size())); + return QRectF(p, QSizeF(mRotateSvgItem->boundingRect().size())); } -QCursor UBGraphicsTriangle::resizeCursor1() const +QCursor UBGraphicsTriangle::resizeCursor1() const { return mResizeCursor1; } -QCursor UBGraphicsTriangle::resizeCursor2() const +QCursor UBGraphicsTriangle::resizeCursor2() const { return mResizeCursor2; } -QCursor UBGraphicsTriangle::flipCursor() const +QCursor UBGraphicsTriangle::flipCursor() const { - return Qt::ArrowCursor; + return Qt::ArrowCursor; } void UBGraphicsTriangle::mousePressEvent(QGraphicsSceneMouseEvent *event) { - if (resize1Polygon().containsPoint(event->pos().toPoint(), Qt::OddEvenFill)) + lastRect = rect().toRect(); + lastPos = event->screenPos(); + + if (resize1Polygon().containsPoint(event->pos().toPoint(), Qt::OddEvenFill)) { mResizing1 = true; event->accept(); } - else if (resize2Polygon().containsPoint(event->pos().toPoint(), Qt::OddEvenFill)) + else + if (resize2Polygon().containsPoint(event->pos().toPoint(), Qt::OddEvenFill)) + { + mResizing2 = true; + event->accept(); + } + else + if(rotateRect().contains(event->pos())) { - mResizing2 = true; + mRotating = true; event->accept(); } - else if(rotateRect().contains(event->pos())) - { - mRotating = true; - event->accept(); - } else { - QGraphicsItem::mousePressEvent(event); + QGraphicsItem::mousePressEvent(event); } - mShowButtons = false; - mCloseSvgItem->setVisible(false); - mHFlipSvgItem->setVisible(false); - mVFlipSvgItem->setVisible(false); - mRotateSvgItem->setVisible(mRotating); - update(); + mShowButtons = false; + mCloseSvgItem->setVisible(false); + mHFlipSvgItem->setVisible(false); + mVFlipSvgItem->setVisible(false); + mRotateSvgItem->setVisible(mRotating); + update(); } void UBGraphicsTriangle::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { + + QPoint currPos = event->screenPos(); +// qDebug() << QString(" X: %1 ").arg(currPos.x()); +// qDebug() << QString(" Y: %1 ").arg(currPos.y()); + if (!mResizing1 && !mResizing2 && !mRotating) { - QGraphicsItem::mouseMoveEvent(event); + QGraphicsItem::mouseMoveEvent(event); } else { - if (mResizing1) - { - QPointF delta = event->pos() - event->lastPos(); + + //-----------------------------------------------// + + if (mResizing1) + { if (mOrientation == TopLeft || mOrientation == BottomLeft) { - if (rect().width() + delta.x() < (qreal)sMinWidth) - delta.setX((qreal)sMinWidth - rect().width()); + int deltaX = currPos.x() - lastPos.x(); + if (lastRect.width() + deltaX < sMinWidth) + deltaX = sMinWidth - lastRect.width(); + + setRect(QRectF(lastRect.left(), lastRect.top(), + lastRect.width() + deltaX, lastRect.height()), mOrientation); } else { - if (rect().width() - delta.x() < (qreal)sMinWidth) - delta.setX((qreal)sMinWidth - rect().width()); + int deltaX = lastPos.x() - currPos.x(); + if (lastRect.width() + deltaX < sMinWidth) + deltaX = sMinWidth - lastRect.width(); + + setRect(QRectF(lastRect.left() - deltaX, lastRect.top(), + lastRect.width() + deltaX, lastRect.height()), mOrientation); } - if (mOrientation == TopLeft || mOrientation == BottomLeft) - { - setRect(QRectF( - rect().topLeft(), - QSizeF(rect().width() + delta.x(), - rect().height())), - mOrientation); - } - else - { - setRect(QRectF( - rect().left() + delta.x(), - rect().top(), - rect().width() - delta.x(), - rect().height()), - mOrientation - ); - } - } - if (mResizing2) - { - QPointF delta = event->pos() - event->lastPos(); + } + + //-----------------------------------------------// + + if (mResizing2) + { if (mOrientation == BottomRight || mOrientation == BottomLeft) { - if (rect().height() - delta.y() < (qreal)sMinHeight) - delta.setY((qreal)sMinHeight - rect().height()); + int deltaY = lastPos.y() - currPos.y(); + if (lastRect.height() + deltaY < sMinHeight) + deltaY = sMinHeight - lastRect.height(); + + setRect(QRectF(lastRect.left(), lastRect.top() - deltaY, + lastRect.width(), lastRect.height() + deltaY), mOrientation); } else { - if (rect().height() + delta.y() < (qreal)sMinHeight) - delta.setY((qreal)sMinHeight - rect().height()); + int deltaY = currPos.y() - lastPos.y(); + if (lastRect.height() + deltaY < sMinHeight) + deltaY = sMinHeight - lastRect.height(); + + setRect(QRectF(lastRect.left(), lastRect.top(), + lastRect.width(), lastRect.height() + deltaY), mOrientation); } - if (mOrientation == BottomRight || mOrientation == BottomLeft) - setRect(QRectF( - rect().left(), - rect().top() + delta.y(), - rect().width(), - rect().height() - delta.y()), - mOrientation); - else - setRect(QRectF( - rect().left(), - rect().top(), - rect().width(), - rect().height() + delta.y()), - mOrientation); - } + + } + + //-----------------------------------------------// + if (mRotating) { QLineF currentLine(rotationCenter(), event->pos()); @@ -669,104 +671,106 @@ void UBGraphicsTriangle::mouseMoveEvent(QGraphicsSceneMouseEvent *event) rotateAroundCenter(currentLine.angleTo(lastLine)); } + //-----------------------------------------------// + event->accept(); } } void UBGraphicsTriangle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { - if (mResizing1 || mResizing2 || mRotating) + if (mResizing1 || mResizing2 || mRotating) { if (mRotating) updateResizeCursor(); mResizing1 = false; - mResizing2 = false; - mRotating = false; + mResizing2 = false; + mRotating = false; event->accept(); } else if (closeButtonRect().contains(event->pos())) { - hide(); - emit hidden(); + hide(); + emit hidden(); event->accept(); } - else if (hFlipRect().contains(event->pos())) - { - switch(mOrientation) - { - case BottomLeft: - setOrientation(BottomRight); - break; - case BottomRight: - setOrientation(BottomLeft); - break; - case TopLeft: - setOrientation(TopRight); - break; - case TopRight: - setOrientation(TopLeft); - break; - } - } - else if (vFlipRect().contains(event->pos())) - { - switch(mOrientation) - { - case BottomLeft: - setOrientation(TopLeft); - break; - case BottomRight: - setOrientation(TopRight); - break; - case TopLeft: - setOrientation(BottomLeft); - break; - case TopRight: - setOrientation(BottomRight); - break; - } - } + else if (hFlipRect().contains(event->pos())) + { + switch(mOrientation) + { + case BottomLeft: + setOrientation(BottomRight); + break; + case BottomRight: + setOrientation(BottomLeft); + break; + case TopLeft: + setOrientation(TopRight); + break; + case TopRight: + setOrientation(TopLeft); + break; + } + } + else if (vFlipRect().contains(event->pos())) + { + switch(mOrientation) + { + case BottomLeft: + setOrientation(TopLeft); + break; + case BottomRight: + setOrientation(TopRight); + break; + case TopLeft: + setOrientation(BottomLeft); + break; + case TopRight: + setOrientation(BottomRight); + break; + } + } else { - QGraphicsItem::mouseReleaseEvent(event); + QGraphicsItem::mouseReleaseEvent(event); } - mShowButtons = true; - update(); + mShowButtons = true; + update(); if (scene()) scene()->setModified(true); } void UBGraphicsTriangle::hoverEnterEvent(QGraphicsSceneHoverEvent *event) { - UBStylusTool::Enum currentTool = (UBStylusTool::Enum)UBDrawingController::drawingController ()->stylusTool (); + UBStylusTool::Enum currentTool = (UBStylusTool::Enum)UBDrawingController::drawingController ()->stylusTool (); - if (currentTool == UBStylusTool::Selector) - { - mCloseSvgItem->setParentItem(this); + if (currentTool == UBStylusTool::Selector) + { + mCloseSvgItem->setParentItem(this); - mShowButtons = true; - mCloseSvgItem->setVisible(true); - mHFlipSvgItem->setVisible(true); - mVFlipSvgItem->setVisible(true); - mRotateSvgItem->setVisible(true); + mShowButtons = true; + mCloseSvgItem->setVisible(true); + mHFlipSvgItem->setVisible(true); + mVFlipSvgItem->setVisible(true); + mRotateSvgItem->setVisible(true); - if (resize1Polygon().containsPoint(event->pos().toPoint(), Qt::OddEvenFill)) + if (resize1Polygon().containsPoint(event->pos().toPoint(), Qt::OddEvenFill)) setCursor(resizeCursor1()); else if(resize2Polygon().containsPoint(event->pos().toPoint(), Qt::OddEvenFill)) - setCursor(resizeCursor2()); - else if (closeButtonRect().contains(event->pos())) - setCursor(closeCursor()); - else if (hFlipRect().contains(event->pos()) - || vFlipRect().contains(event->pos())) - setCursor(flipCursor()); - else if (rotateRect().contains(event->pos())) - setCursor(rotateCursor()); - else - setCursor(moveCursor()); - - event->accept(); - update(); - } + setCursor(resizeCursor2()); + else if (closeButtonRect().contains(event->pos())) + setCursor(closeCursor()); + else if (hFlipRect().contains(event->pos()) + || vFlipRect().contains(event->pos())) + setCursor(flipCursor()); + else if (rotateRect().contains(event->pos())) + setCursor(rotateCursor()); + else + setCursor(moveCursor()); + + event->accept(); + update(); + } } void UBGraphicsTriangle::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) @@ -774,8 +778,8 @@ void UBGraphicsTriangle::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) mShowButtons = false; setCursor(Qt::ArrowCursor); mCloseSvgItem->setVisible(false); - mVFlipSvgItem->setVisible(false); - mHFlipSvgItem->setVisible(false); + mVFlipSvgItem->setVisible(false); + mHFlipSvgItem->setVisible(false); mRotateSvgItem->setVisible(false); event->accept(); update(); @@ -783,29 +787,29 @@ void UBGraphicsTriangle::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) void UBGraphicsTriangle::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { - UBStylusTool::Enum currentTool = (UBStylusTool::Enum)UBDrawingController::drawingController ()->stylusTool (); + UBStylusTool::Enum currentTool = (UBStylusTool::Enum)UBDrawingController::drawingController ()->stylusTool (); - if (currentTool == UBStylusTool::Selector) - { - mCloseSvgItem->setVisible(mShowButtons); - mVFlipSvgItem->setVisible(mShowButtons); - mHFlipSvgItem->setVisible(mShowButtons); - mRotateSvgItem->setVisible(mShowButtons); + if (currentTool == UBStylusTool::Selector) + { + mCloseSvgItem->setVisible(mShowButtons); + mVFlipSvgItem->setVisible(mShowButtons); + mHFlipSvgItem->setVisible(mShowButtons); + mRotateSvgItem->setVisible(mShowButtons); - if (resize1Polygon().containsPoint(event->pos().toPoint(), Qt::OddEvenFill)) + if (resize1Polygon().containsPoint(event->pos().toPoint(), Qt::OddEvenFill)) setCursor(resizeCursor1()); else if (resize2Polygon().containsPoint(event->pos().toPoint(), Qt::OddEvenFill)) - setCursor(resizeCursor2()); - else if (closeButtonRect().contains(event->pos())) - setCursor(closeCursor()); - else if (hFlipRect().contains(event->pos()) - || vFlipRect().contains(event->pos())) - setCursor(flipCursor()); - else if (rotateRect().contains(event->pos())) - setCursor(rotateCursor()); - else - setCursor(moveCursor()); - - event->accept(); - } + setCursor(resizeCursor2()); + else if (closeButtonRect().contains(event->pos())) + setCursor(closeCursor()); + else if (hFlipRect().contains(event->pos()) + || vFlipRect().contains(event->pos())) + setCursor(flipCursor()); + else if (rotateRect().contains(event->pos())) + setCursor(rotateCursor()); + else + setCursor(moveCursor()); + + event->accept(); + } } diff --git a/src/tools/UBGraphicsTriangle.h b/src/tools/UBGraphicsTriangle.h index 43ca9008..e541a280 100644 --- a/src/tools/UBGraphicsTriangle.h +++ b/src/tools/UBGraphicsTriangle.h @@ -36,7 +36,7 @@ class UBGraphicsTriangle : public UBAbstractDrawRuler, public QGraphicsPolygonIt UBGraphicsTriangle(); virtual ~UBGraphicsTriangle(); - enum { Type = UBGraphicsItemType::TriangleItemType }; + enum { Type = UBGraphicsItemType::TriangleItemType }; virtual int type() const { @@ -44,64 +44,64 @@ class UBGraphicsTriangle : public UBAbstractDrawRuler, public QGraphicsPolygonIt } - virtual UBItem* deepCopy(void) const; - - enum UBGraphicsTriangleOrientation - { - BottomLeft = 0, - BottomRight, - TopLeft, - TopRight - }; - - static UBGraphicsTriangleOrientation orientationFromStr(QStringRef& str) - { - if (str == "BottomLeft") return BottomLeft; - if (str == "BottomRight") return BottomRight; - if (str == "TopLeft") return TopLeft; - if (str == "TopRight") return TopRight; - return sDefaultOrientation; - } - void setRect(const QRectF &rect, UBGraphicsTriangleOrientation orientation) - { - setRect(rect.x(), rect.y(), rect.width(), rect.height(), orientation); - } - void setRect(qreal x, qreal y, qreal w, qreal h, UBGraphicsTriangleOrientation orientation); - void setOrientation(UBGraphicsTriangleOrientation orientation); - QRectF rect() const {return boundingRect();} - - UBGraphicsScene* scene() const; - - protected: + virtual UBItem* deepCopy(void) const; + + enum UBGraphicsTriangleOrientation + { + BottomLeft = 0, + BottomRight, + TopLeft, + TopRight + }; + + static UBGraphicsTriangleOrientation orientationFromStr(QStringRef& str) + { + if (str == "BottomLeft") return BottomLeft; + if (str == "BottomRight") return BottomRight; + if (str == "TopLeft") return TopLeft; + if (str == "TopRight") return TopRight; + return sDefaultOrientation; + } + void setRect(const QRectF &rect, UBGraphicsTriangleOrientation orientation) + { + setRect(rect.x(), rect.y(), rect.width(), rect.height(), orientation); + } + void setRect(qreal x, qreal y, qreal w, qreal h, UBGraphicsTriangleOrientation orientation); + void setOrientation(UBGraphicsTriangleOrientation orientation); + QRectF rect() const {return boundingRect();} + + UBGraphicsScene* scene() const; + + protected: void updateResizeCursor(); - virtual void paint (QPainter *painter, const QStyleOptionGraphicsItem *styleOption, QWidget *widget); + virtual void paint (QPainter *painter, const QStyleOptionGraphicsItem *styleOption, QWidget *widget); - virtual void rotateAroundCenter(qreal angle); + virtual void rotateAroundCenter(qreal angle); - virtual QPointF rotationCenter() const; + virtual QPointF rotationCenter() const; - virtual QRectF closeButtonRect() const; - QPolygonF resize1Polygon() const; - QPolygonF resize2Polygon() const; - QRectF hFlipRect() const; - QRectF vFlipRect() const; - QRectF rotateRect() const; + virtual QRectF closeButtonRect() const; + QPolygonF resize1Polygon() const; + QPolygonF resize2Polygon() const; + QRectF hFlipRect() const; + QRectF vFlipRect() const; + QRectF rotateRect() const; - QCursor resizeCursor1() const; - QCursor resizeCursor2() const; + QCursor resizeCursor1() const; + QCursor resizeCursor2() const; - QCursor flipCursor() const; + QCursor flipCursor() const; - virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event); - virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); - virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event); - virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); - virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event); + virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); + virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event); - private: + private: QCursor mResizeCursor1; QCursor mResizeCursor2; @@ -110,21 +110,23 @@ class UBGraphicsTriangle : public UBAbstractDrawRuler, public QGraphicsPolygonIt qreal angle; void rotateAroundCenter(QTransform& transform, QPointF center); - bool mResizing1; - bool mResizing2; - bool mRotating; + bool mResizing1; + bool mResizing2; + bool mRotating; + QRect lastRect; + QPoint lastPos; - QGraphicsSvgItem* mHFlipSvgItem; - QGraphicsSvgItem* mVFlipSvgItem; - QGraphicsSvgItem* mRotateSvgItem; + QGraphicsSvgItem* mHFlipSvgItem; + QGraphicsSvgItem* mVFlipSvgItem; + QGraphicsSvgItem* mRotateSvgItem; - static const QRect sDefaultRect; - static const UBGraphicsTriangleOrientation sDefaultOrientation; + static const QRect sDefaultRect; + static const UBGraphicsTriangleOrientation sDefaultOrientation; - void paintGraduations(QPainter *painter); + void paintGraduations(QPainter *painter); - UBGraphicsTriangleOrientation mOrientation; + UBGraphicsTriangleOrientation mOrientation; QPointF A1, B1, C1, A2, B2, C2; // coordinates of points in ext and int triangles qreal C; @@ -132,10 +134,10 @@ class UBGraphicsTriangle : public UBAbstractDrawRuler, public QGraphicsPolygonIt QPointF CC; // Hyp. fillining gradient - top point void calculatePoints(const QRectF& rect); - static const int d = 70; // width of triangle border - static const int sArrowLength = 30; - static const int sMinWidth = 380; - static const int sMinHeight = 200; + static const int d = 70; // width of triangle border + static const int sArrowLength = 30; + static const int sMinWidth = 380; + static const int sMinHeight = 200; }; #endif /* UBGRAPHICSTRIANGLE_H_ */