clapp-pm 1.0.44__py3-none-any.whl → 1.0.45__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,556 +0,0 @@
1
- """
2
- Rain Desktop - Masaüstü Alanı
3
- PyCloud OS için masaüstü simgeleri ve etkileşim alanı
4
- """
5
-
6
- import logging
7
- import os
8
- from typing import List, Dict, Optional
9
- from pathlib import Path
10
-
11
- try:
12
- from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel,
13
- QPushButton, QGridLayout, QScrollArea,
14
- QFrame)
15
- from PyQt6.QtCore import Qt, QSize, pyqtSignal, QTimer
16
- from PyQt6.QtGui import QFont, QPixmap, QPainter, QColor, QBrush
17
- PYQT_AVAILABLE = True
18
- except ImportError:
19
- PYQT_AVAILABLE = False
20
-
21
- class DesktopIcon(QPushButton):
22
- """Masaüstü simgesi widget'ı"""
23
-
24
- double_clicked = pyqtSignal(str) # file_path
25
-
26
- def __init__(self, name: str, file_path: str, icon_text: str = "📄"):
27
- super().__init__()
28
- self.name = name
29
- self.file_path = file_path
30
- self.icon_text = icon_text
31
-
32
- self.setup_ui()
33
-
34
- def setup_ui(self):
35
- """Simge arayüzünü kur"""
36
- self.setFixedSize(90, 120)
37
- self.setText(f"{self.icon_text}\n{self.name}")
38
- self.setFont(QFont("Arial", 10))
39
- self.setToolTip(self.file_path)
40
-
41
- self.setStyleSheet("""
42
- QPushButton {
43
- background-color: transparent;
44
- border: 2px solid transparent;
45
- border-radius: 10px;
46
- color: #ffffff;
47
- text-align: center;
48
- padding: 8px;
49
- font-weight: bold;
50
- }
51
-
52
- QPushButton:hover {
53
- background-color: rgba(255, 255, 255, 0.1);
54
- border-color: rgba(255, 255, 255, 0.2);
55
- }
56
-
57
- QPushButton:pressed {
58
- background-color: rgba(255, 255, 255, 0.15);
59
- }
60
- """)
61
-
62
- def mouseDoubleClickEvent(self, event):
63
- """Çift tıklama olayı"""
64
- if event.button() == Qt.MouseButton.LeftButton:
65
- self.double_clicked.emit(self.file_path)
66
- super().mouseDoubleClickEvent(event)
67
-
68
- class RainDesktop(QWidget):
69
- """Rain UI Desktop bileşeni"""
70
-
71
- def __init__(self, kernel):
72
- super().__init__()
73
- self.kernel = kernel
74
- self.logger = logging.getLogger("RainDesktop")
75
-
76
- if not PYQT_AVAILABLE:
77
- return
78
-
79
- self.desktop_icons: List[DesktopIcon] = []
80
- self.desktop_files: List[Dict] = []
81
-
82
- self.setup_ui()
83
- self.load_desktop_items()
84
-
85
- # Periyodik güncelleme
86
- self.update_timer = QTimer()
87
- self.update_timer.timeout.connect(self.refresh_desktop)
88
- self.update_timer.start(10000) # Her 10 saniyede güncelle
89
-
90
- def setup_ui(self):
91
- """Arayüzü kur"""
92
- self.setStyleSheet("""
93
- QWidget {
94
- background-color: transparent;
95
- color: #ffffff;
96
- }
97
- """)
98
-
99
- # Ana layout - sadece simgeler için
100
- main_layout = QGridLayout(self)
101
- main_layout.setContentsMargins(30, 30, 30, 30)
102
- main_layout.setSpacing(20)
103
- main_layout.setAlignment(Qt.AlignmentFlag.AlignTop | Qt.AlignmentFlag.AlignLeft)
104
-
105
- # Layout'u kaydet
106
- self.desktop_layout = main_layout
107
-
108
- def load_desktop_items(self):
109
- """Masaüstü öğelerini yükle"""
110
- try:
111
- # Basitleştirilmiş desktop path - doğrudan pycloud_fs/home/Desktop
112
- desktop_path = Path("pycloud_fs/home/Desktop")
113
- desktop_path.mkdir(parents=True, exist_ok=True)
114
-
115
- self.desktop_files = []
116
-
117
- # Gerçek dosyaları yükle
118
- if desktop_path.exists():
119
- for item in desktop_path.iterdir():
120
- if not item.name.startswith('.'): # Gizli dosyaları atla
121
- self.desktop_files.append({
122
- "name": item.name,
123
- "path": str(item),
124
- "type": "folder" if item.is_dir() else "file",
125
- "icon": self.get_file_icon(item.name)
126
- })
127
-
128
- # Demo dosyaları ekle (eğer masaüstü boşsa)
129
- if not self.desktop_files:
130
- # Hoş geldin dosyası oluştur
131
- welcome_file = desktop_path / "PyCloud OS'e Hoş Geldiniz.md"
132
- if not welcome_file.exists():
133
- welcome_content = """# PyCloud OS'e Hoş Geldiniz! 🎉
134
-
135
- Bu dosya sizin kişisel masaüstünüzde yer almaktadır.
136
-
137
- ## Hızlı Başlangıç
138
-
139
- - 📁 **Dosyalar**: Dock'taki Dosyalar simgesine tıklayarak dosya yöneticinizi açabilirsiniz
140
- - 💻 **Terminal**: Sistem komutları için terminal uygulamasını kullanın
141
- - 🐍 **Python IDE**: Python geliştirme için IDE'yi açın
142
- - ⚙️ **Ayarlar**: Sistem ayarlarını topbar'daki bulut menüsünden erişebilirsiniz
143
-
144
- ## Klasörleriniz
145
-
146
- - **Belgeler**: Dokümanlarınız için
147
- - **İndirilenler**: İndirilen dosyalar
148
- - **Projeler**: Geliştirme projeleri
149
- - **Resimler**: Görseller ve fotoğraflar
150
-
151
- Keyifli kullanımlar! 😊
152
- """
153
- with open(welcome_file, 'w', encoding='utf-8') as f:
154
- f.write(welcome_content)
155
-
156
- # Belgelerim klasörü oluştur - yeni yapıya göre
157
- documents_folder = Path("pycloud_fs/home/Documents")
158
- documents_folder.mkdir(parents=True, exist_ok=True)
159
-
160
- self.desktop_files = [
161
- {
162
- "name": "PyCloud OS'e Hoş Geldiniz.md",
163
- "path": str(welcome_file),
164
- "type": "file",
165
- "icon": "📋"
166
- },
167
- {
168
- "name": "Belgelerim",
169
- "path": str(documents_folder),
170
- "type": "folder",
171
- "icon": "📁"
172
- }
173
- ]
174
-
175
- self.update_desktop_icons()
176
-
177
- except Exception as e:
178
- self.logger.error(f"Failed to load desktop items: {e}")
179
-
180
- def get_file_icon(self, filename: str) -> str:
181
- """Dosya türüne göre ikon döndür"""
182
- ext = filename.split('.')[-1].lower() if '.' in filename else ''
183
-
184
- icon_map = {
185
- 'txt': '📝',
186
- 'md': '📋',
187
- 'py': '🐍',
188
- 'json': '📋',
189
- 'png': '🖼️',
190
- 'jpg': '🖼️',
191
- 'jpeg': '🖼️',
192
- 'pdf': '📄',
193
- 'zip': '📦',
194
- 'folder': '📁'
195
- }
196
-
197
- return icon_map.get(ext, '📄')
198
-
199
- def update_desktop_icons(self):
200
- """Desktop simgelerini güncelle"""
201
- # Mevcut simgeleri temizle
202
- for icon in self.desktop_icons:
203
- icon.setParent(None)
204
- icon.deleteLater()
205
-
206
- self.desktop_icons.clear()
207
-
208
- # Yeni simgeleri oluştur - normal desktop düzeni
209
- row, col = 0, 0
210
- max_cols = 8 # Daha geniş alan kullan
211
-
212
- for file_info in self.desktop_files:
213
- icon = DesktopIcon(
214
- name=file_info["name"],
215
- file_path=file_info["path"],
216
- icon_text=file_info["icon"]
217
- )
218
-
219
- icon.double_clicked.connect(self.open_desktop_item)
220
-
221
- self.desktop_layout.addWidget(icon, row, col)
222
- self.desktop_icons.append(icon)
223
-
224
- col += 1
225
- if col >= max_cols:
226
- col = 0
227
- row += 1
228
-
229
- def open_desktop_item(self, file_path: str):
230
- """Masaüstü öğesini aç"""
231
- self.logger.info(f"Opening desktop item: {file_path}")
232
-
233
- try:
234
- # Dosya türüne göre uygun uygulamayı başlat
235
- if file_path.endswith('.txt') or file_path.endswith('.md'):
236
- self.launch_app_for_file("cloud_notepad", file_path)
237
- elif file_path.endswith('.py'):
238
- self.launch_app_for_file("cloud_pyide", file_path)
239
- elif "folder" in file_path.lower() or os.path.isdir(file_path):
240
- self.launch_app_for_file("cloud.files", file_path)
241
- else:
242
- # Varsayılan dosya yöneticisi ile aç
243
- self.launch_app_for_file("cloud.files", file_path)
244
-
245
- except Exception as e:
246
- self.logger.error(f"Failed to open desktop item {file_path}: {e}")
247
-
248
- def launch_app_for_file(self, app_id: str, file_path: str):
249
- """Dosya için uygulama başlat"""
250
- try:
251
- if self.kernel:
252
- launcher = self.kernel.get_module("launcher")
253
- if launcher:
254
- # PyCloud OS sanal dosya sistemi yolunu kullan
255
- pycloud_path = file_path
256
- if not file_path.startswith(("users/", "apps/", "system/", "temp/")):
257
- # Eğer gerçek dosya sistemi yolu ise, PyCloud OS yoluna çevir
258
- pycloud_path = str(Path("users") / "default" / "Desktop" / Path(file_path).name)
259
-
260
- # Dosya yolu argümanı ile uygulama başlat
261
- launcher.launch_app(app_id, {"open_file": pycloud_path})
262
- self.logger.info(f"Launched {app_id} for file: {pycloud_path}")
263
- else:
264
- self.logger.warning("Launcher module not available")
265
-
266
- except Exception as e:
267
- self.logger.error(f"Failed to launch app {app_id} for file {file_path}: {e}")
268
-
269
- def refresh_desktop(self):
270
- """Masaüstünü yenile"""
271
- try:
272
- self.load_desktop_items()
273
- except Exception as e:
274
- self.logger.error(f"Failed to refresh desktop: {e}")
275
-
276
- def add_desktop_item(self, name: str, path: str, file_type: str):
277
- """Masaüstüne yeni öğe ekle"""
278
- new_item = {
279
- "name": name,
280
- "path": path,
281
- "type": file_type,
282
- "icon": self.get_file_icon(name)
283
- }
284
-
285
- self.desktop_files.append(new_item)
286
- self.update_desktop_icons()
287
-
288
- self.logger.info(f"Added desktop item: {name}")
289
-
290
- def remove_desktop_item(self, path: str):
291
- """Masaüstünden öğe kaldır"""
292
- self.desktop_files = [item for item in self.desktop_files if item["path"] != path]
293
- self.update_desktop_icons()
294
-
295
- self.logger.info(f"Removed desktop item: {path}")
296
-
297
- def contextMenuEvent(self, event):
298
- """Masaüstü sağ tık menüsü"""
299
- self.logger.info(f"Context menu event triggered at position: {event.pos()}")
300
-
301
- try:
302
- # Context menu manager'ı kullan
303
- if self.kernel:
304
- context_menu_manager = self.kernel.get_module("contextmenu")
305
- if context_menu_manager:
306
- self.logger.info("Using context menu manager")
307
- from rain.contextmenu import MenuRequest, MenuType, MenuContext
308
-
309
- # Tıklanan pozisyonda dosya var mı kontrol et
310
- clicked_widget = self.childAt(event.pos())
311
- target_file = None
312
-
313
- if clicked_widget and isinstance(clicked_widget, DesktopIcon):
314
- # Dosya/klasör üzerine tıklandı
315
- target_file = clicked_widget.file_path
316
- file_type = clicked_widget.name.split('.')[-1].lower() if '.' in clicked_widget.name else ''
317
-
318
- self.logger.info(f"Right-clicked on desktop icon: {clicked_widget.name}")
319
-
320
- if clicked_widget.name == "Belgelerim" or "folder" in clicked_widget.file_path.lower():
321
- # Klasör menüsü
322
- request = MenuRequest(
323
- menu_type=MenuType.FOLDER,
324
- context=MenuContext.DESKTOP_FOLDER,
325
- target_path=target_file,
326
- position=event.globalPos(),
327
- widget=self,
328
- extra_data={"icon_widget": clicked_widget}
329
- )
330
- else:
331
- # Dosya menüsü
332
- request = MenuRequest(
333
- menu_type=MenuType.FILE,
334
- context=MenuContext.DESKTOP_FILE,
335
- target_path=target_file,
336
- position=event.globalPos(),
337
- widget=self,
338
- extra_data={"icon_widget": clicked_widget, "file_type": file_type}
339
- )
340
- else:
341
- # Boş alan menüsü
342
- self.logger.info("Right-clicked on empty desktop area")
343
- request = MenuRequest(
344
- menu_type=MenuType.DESKTOP,
345
- context=MenuContext.DESKTOP_EMPTY,
346
- position=event.globalPos(),
347
- widget=self,
348
- extra_data={"click_pos": event.pos()}
349
- )
350
-
351
- # Context menu'yu göster
352
- success = context_menu_manager.show_context_menu(request)
353
- self.logger.info(f"Context menu show result: {success}")
354
- return
355
- else:
356
- self.logger.warning("Context menu manager not found, using fallback")
357
- else:
358
- self.logger.warning("Kernel not available, using fallback")
359
-
360
- # Fallback: basit menü
361
- self.logger.info("Using fallback context menu")
362
- self._show_fallback_menu(event)
363
-
364
- except Exception as e:
365
- self.logger.error(f"Context menu error: {e}")
366
- import traceback
367
- self.logger.error(traceback.format_exc())
368
- self._show_fallback_menu(event)
369
-
370
- def _show_fallback_menu(self, event):
371
- """Fallback basit menü"""
372
- try:
373
- from PyQt6.QtWidgets import QMenu
374
- from PyQt6.QtGui import QAction
375
-
376
- menu = QMenu(self)
377
- menu.setStyleSheet("""
378
- QMenu {
379
- background-color: rgba(45, 45, 45, 0.95);
380
- border: 1px solid rgba(80, 80, 80, 0.8);
381
- border-radius: 8px;
382
- padding: 6px;
383
- color: #ffffff;
384
- }
385
-
386
- QMenu::item {
387
- background-color: transparent;
388
- padding: 10px 18px;
389
- border-radius: 6px;
390
- margin: 1px;
391
- color: #ffffff;
392
- }
393
-
394
- QMenu::item:selected {
395
- background-color: rgba(70, 70, 70, 0.8);
396
- }
397
-
398
- QMenu::separator {
399
- height: 1px;
400
- background-color: rgba(100, 100, 100, 0.6);
401
- margin: 6px 12px;
402
- }
403
- """)
404
-
405
- # Yeni menüsü
406
- new_menu = menu.addMenu("📄 Yeni")
407
-
408
- new_text_action = QAction("📝 Metin Belgesi", self)
409
- new_text_action.triggered.connect(lambda: self.create_new_file("text"))
410
- new_menu.addAction(new_text_action)
411
-
412
- new_python_action = QAction("🐍 Python Dosyası", self)
413
- new_python_action.triggered.connect(lambda: self.create_new_file("python"))
414
- new_menu.addAction(new_python_action)
415
-
416
- new_folder_action = QAction("📁 Klasör", self)
417
- new_folder_action.triggered.connect(self.create_new_folder)
418
- new_menu.addAction(new_folder_action)
419
-
420
- menu.addSeparator()
421
-
422
- # Yenile
423
- refresh_action = QAction("🔄 Yenile", self)
424
- refresh_action.triggered.connect(self.refresh_desktop)
425
- menu.addAction(refresh_action)
426
-
427
- menu.addSeparator()
428
-
429
- # Duvar kağıdı değiştir
430
- wallpaper_action = QAction("🖼️ Duvar Kağıdı Değiştir", self)
431
- wallpaper_action.triggered.connect(self.change_wallpaper)
432
- menu.addAction(wallpaper_action)
433
-
434
- # Özelleştir
435
- customize_action = QAction("🎨 Masaüstü Ayarları", self)
436
- customize_action.triggered.connect(self.open_desktop_settings)
437
- menu.addAction(customize_action)
438
-
439
- menu.exec(event.globalPos())
440
-
441
- except ImportError:
442
- pass
443
-
444
- def create_new_file(self, file_type: str):
445
- """Yeni dosya oluştur"""
446
- try:
447
- # Yeni yapıya uygun desktop path
448
- desktop_path = Path("pycloud_fs/home/Desktop")
449
-
450
- if file_type == "text":
451
- filename = "Yeni Metin Belgesi.txt"
452
- filepath = desktop_path / filename
453
- counter = 1
454
- while filepath.exists():
455
- filename = f"Yeni Metin Belgesi ({counter}).txt"
456
- filepath = desktop_path / filename
457
- counter += 1
458
-
459
- # Basit içerikle dosya oluştur
460
- with open(filepath, 'w', encoding='utf-8') as f:
461
- f.write("Bu yeni bir metin belgesidir.\n\nBuraya notlarınızı yazabilirsiniz.")
462
-
463
- elif file_type == "python":
464
- filename = "yeni_script.py"
465
- filepath = desktop_path / filename
466
- counter = 1
467
- while filepath.exists():
468
- filename = f"yeni_script_{counter}.py"
469
- filepath = desktop_path / filename
470
- counter += 1
471
-
472
- # Python şablonu
473
- with open(filepath, 'w', encoding='utf-8') as f:
474
- f.write('#!/usr/bin/env python3\n"""\nYeni Python Script\n"""\n\nprint("Merhaba PyCloud OS!")\n')
475
-
476
- elif file_type == "markdown":
477
- filename = "Not Defteri.md"
478
- filepath = desktop_path / filename
479
- counter = 1
480
- while filepath.exists():
481
- filename = f"Not Defteri ({counter}).md"
482
- filepath = desktop_path / filename
483
- counter += 1
484
-
485
- # Markdown şablonu
486
- with open(filepath, 'w', encoding='utf-8') as f:
487
- f.write("# Yeni Not\n\n## Başlık\n\nBuraya notlarınızı markdown formatında yazabilirsiniz.\n\n- Liste öğesi 1\n- Liste öğesi 2\n")
488
-
489
- # Desktop'u yenile
490
- self.load_desktop_items()
491
- self.logger.info(f"Created new file: {filepath}")
492
-
493
- except Exception as e:
494
- self.logger.error(f"Failed to create new file: {e}")
495
-
496
- def create_new_folder(self):
497
- """Yeni klasör oluştur"""
498
- try:
499
- # Yeni yapıya uygun desktop path
500
- desktop_path = Path("pycloud_fs/home/Desktop")
501
-
502
- folder_name = "Yeni Klasör"
503
- folder_path = desktop_path / folder_name
504
- counter = 1
505
-
506
- while folder_path.exists():
507
- folder_name = f"Yeni Klasör ({counter})"
508
- folder_path = desktop_path / folder_name
509
- counter += 1
510
-
511
- folder_path.mkdir()
512
-
513
- # Desktop'u yenile
514
- self.load_desktop_items()
515
- self.logger.info(f"Created new folder: {folder_path}")
516
-
517
- except Exception as e:
518
- self.logger.error(f"Failed to create new folder: {e}")
519
-
520
- def open_desktop_settings(self):
521
- """Desktop ayarlarını aç"""
522
- self.logger.info("Opening desktop settings")
523
- try:
524
- # Settings uygulamasını başlat
525
- self.launch_app_for_file("cloud.settings", "desktop")
526
- except Exception as e:
527
- self.logger.error(f"Failed to open desktop settings: {e}")
528
-
529
- def change_wallpaper(self):
530
- """Duvar kağıdı değiştir"""
531
- try:
532
- if self.kernel:
533
- wallpaper_manager = self.kernel.get_module("wallpaper")
534
- if wallpaper_manager:
535
- wallpaper_manager.show_wallpaper_dialog()
536
- else:
537
- self.logger.warning("Wallpaper manager not available")
538
- except Exception as e:
539
- self.logger.error(f"Failed to change wallpaper: {e}")
540
-
541
- def get_default_app_for_file(self, file_path: str) -> str:
542
- """Dosya için varsayılan uygulamayı belirle"""
543
- file_ext = Path(file_path).suffix.lower()
544
-
545
- # Dosya uzantısına göre varsayılan uygulama
546
- default_apps = {
547
- ".txt": "cloud_notepad",
548
- ".md": "cloud_notepad",
549
- ".py": "cloud_pyide",
550
- ".json": "cloud_notepad",
551
- ".log": "cloud_notepad",
552
- ".html": "cloud_browser",
553
- ".pdf": "cloud_browser",
554
- }
555
-
556
- return default_apps.get(file_ext, "cloud_notepad")